Skip to content

Commit

Permalink
Fix broken automatic manifest update after configurable interval
Browse files Browse the repository at this point in the history
  • Loading branch information
guilledk committed Mar 25, 2024
1 parent 9bfb1e1 commit c4c307f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 42 deletions.
37 changes: 28 additions & 9 deletions plugins/subst_plugin/subst_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ namespace eosio {

class subst_plugin_impl : public std::enable_shared_from_this<subst_plugin_impl> {
private:
boost::asio::io_service& _io;
boost::asio::steady_timer manifest_timer;

public:
subst_plugin_impl(boost::asio::io_service& io)
: _io(io)
: manifest_timer(io)
{}

substitution_context* subst_ctx;
Expand All @@ -21,18 +21,17 @@ namespace eosio {

bool override_tx_time = false;
bool should_perform_override = false;
uint32_t override_time = 300;
uint32_t override_time = DEFAULT_OVERRIDE_TIME;
uint32_t manifest_interval = DEFAULT_MANIFEST_INTERVAL;

void init(chain_plugin* chain, const variables_map& options) {
app_options = options;

control = &chain->chain();
db = &control->mutable_db();
subst_ctx = new substitution_context(
control,
_io,
app_options.at("subst-manifest-interval").as<uint32_t>()
);
subst_ctx = new substitution_context(control);

manifest_interval = app_options.at("subst-manifest-interval").as<uint32_t>();

control->get_wasm_interface().substitute_apply = [&](
const chain::digest_type& code_hash,
Expand Down Expand Up @@ -116,11 +115,31 @@ namespace eosio {
);
subst_ctx->manifest_url = manifest_url;
subst_ctx->fetch_manifest();
schedule_manifest_update();
}

subst_ctx->debug_print();
}

void schedule_manifest_update() {
ilog("scheduling manifest update in ${i}", ("i",manifest_interval));
manifest_timer.expires_from_now(std::chrono::seconds(manifest_interval));
manifest_timer.async_wait(
app().executor().wrap(
priority::high,
exec_queue::read_write,
[weak_this = weak_from_this()]( const boost::system::error_code& ec ) {
auto self = weak_this.lock();
if(self && ec != boost::asio::error::operation_aborted) {
ilog("trigger manifest update");
self->subst_ctx->fetch_manifest();
self->schedule_manifest_update();
}
}
)
);
}

void pwn_gpo() {
const auto& gpo = control->get_global_properties();
const auto override_time_us = override_time * 1000;
Expand Down Expand Up @@ -187,7 +206,7 @@ namespace eosio {
"subst-manifest", bpo::value<string>()->default_value(std::string("")),
"url. load susbtitution information from a remote json file.");
options(
"subst-manifest-interval", bpo::value<uint32_t>()->default_value(300),
"subst-manifest-interval", bpo::value<uint32_t>()->default_value(DEFAULT_MANIFEST_INTERVAL),
"Time between manifest re-fetches");
options(
"override-max-tx-time", bpo::value<uint32_t>(),
Expand Down
4 changes: 4 additions & 0 deletions plugins/subst_plugin/subst_plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include "substitution_context.hpp"


#define DEFAULT_OVERRIDE_TIME 300
#define DEFAULT_MANIFEST_INTERVAL 300


namespace eosio {

using chain::controller;
Expand Down
28 changes: 13 additions & 15 deletions plugins/subst_plugin/substitution_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ namespace eosio {
}


const digest_type substitution_context::get_codeobj_hash(const name& account) {
const auto& cobj = get_codeobj(account);
const digest_type substitution_context::get_codeobj_hash(const name& account, bool check_result) {
const auto& cobj = get_codeobj(account, check_result);
if (!cobj && !check_result) return digest_type();
return digest_type::hash((const char*)cobj->code.data(), cobj->code.size());
}

Expand Down Expand Up @@ -206,8 +207,10 @@ namespace eosio {


void substitution_context::deactivate(const name& account) {
const auto& meta = get_by_account(account);
const auto& cobj = get_codeobj(account);
const auto& meta = get_by_account(account, false);
const auto& cobj = get_codeobj(account, false);

if (!cobj) return;

const digest_type& cobj_hash = get_codeobj_hash(account);

Expand Down Expand Up @@ -236,7 +239,10 @@ namespace eosio {


void substitution_context::remove(const name& account) {
const subst_meta_object* acc = get_by_account(account);
const subst_meta_object* acc = get_by_account(account, false);

if (!acc) return;

db->remove(*acc);
ilog("removed substitution metadata for ${acc}", ("acc", account));
}
Expand Down Expand Up @@ -312,6 +318,8 @@ namespace eosio {
wlog("looks like provided url based substitution manifest"
"doesn\'t end with \"susbt.json\"... trying anyways...");

ilog("fetching manifest at ${url}", ("url", target_url));
fc::http_client httpc;
fc::variant manifest = httpc.get_sync_json(target_url);
auto& manif_obj = manifest.get_object();

Expand Down Expand Up @@ -349,14 +357,4 @@ namespace eosio {
}
}

void substitution_context::manifest_fetcher_task() {
if (!manifest_url) return;
ilog("running manifest update");
fetch_manifest();
manifest_timer.expires_after(manifest_fetch_interval);
manifest_timer.async_wait(
boost::bind(
&substitution_context::manifest_fetcher_task, shared_from_this()));
}

} // namespace eosio
23 changes: 5 additions & 18 deletions plugins/subst_plugin/substitution_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,16 @@ namespace eosio {
class substitution_context : public std::enable_shared_from_this<substitution_context> {
public:
std::optional<fc::url> manifest_url;
std::chrono::seconds manifest_fetch_interval;

substitution_context(
chain::controller* _control,
boost::asio::io_service& _io,
uint32_t _manifest_refetch_interval
) :
manifest_fetch_interval(_manifest_refetch_interval),

substitution_context(chain::controller* _control) :
control(_control),
db(&_control->mutable_db()),
manifest_timer(_io)
db(&_control->mutable_db())
{}

// nodeos code store getters
const account_metadata_object* get_account_metadata_object(const name& account, bool check_result = true);
const code_object* get_codeobj(const name& account, bool check_result = true);
const digest_type get_codeobj_hash(const name& account);
const digest_type get_codeobj_hash(const name& account, bool check_result = true);

// upsert
void upsert(std::string info, const std::vector<uint8_t>& code, bool must_activate = true);
Expand Down Expand Up @@ -139,18 +132,12 @@ namespace eosio {
}
#endif

// perform immidiate manifest update
// perform manifest update
void fetch_manifest();

private:
chain::controller* control;
chainbase::database* db;
fc::http_client httpc;

// timer for manifest update task
boost::asio::steady_timer manifest_timer;

void manifest_fetcher_task();

// register new substitution, starts with on chain contract info zeroed out
// will get filled on first use
Expand Down

0 comments on commit c4c307f

Please sign in to comment.