Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Limiting WASM exectuion time #67

Merged
merged 11 commits into from
Jul 25, 2017
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions libraries/chain/include/eos/chain/wasm_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

namespace eos { namespace chain {

struct checktime_exceeded : public fc::exception
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should define exceptions in eos/chain/exceptions.hpp

{
};

class chain_controller;

/**
Expand Down
30 changes: 29 additions & 1 deletion libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "IR/Validate.h"
#include <eos/chain/key_value_object.hpp>
#include <eos/chain/account_object.hpp>
#include <chrono>

namespace eos { namespace chain {
using namespace IR;
Expand All @@ -17,6 +18,22 @@ namespace eos { namespace chain {
wasm_interface::wasm_interface() {
}

std::chrono::time_point<std::chrono::system_clock> checktimeStart;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This global needs to be moved into the wasm_interface member data

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also it should be an fc::time_point


#ifdef NDEBUG
const int CHECKTIME_LIMIT = 2000;
#else
const int CHECKTIME_LIMIT = 12000;
#endif

DEFINE_INTRINSIC_FUNCTION0(env,checktime,checktime,none) {
auto dur = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - checktimeStart);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fc::time_point::now() is a shorter way to write this.

if (dur.count() > CHECKTIME_LIMIT) {
wlog("checktime called ${d}", ("d", dur.count()));
throw checktime_exceeded();
}
}

DEFINE_INTRINSIC_FUNCTION4(env,store,store,none,i32,keyptr,i32,keylen,i32,valueptr,i32,valuelen ) {
// ilog( "store ${keylen} ${vallen}", ("keylen",keylen)("vallen",valuelen) );
/*
Expand Down Expand Up @@ -245,6 +262,11 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
// return 0;
}

DEFINE_INTRINSIC_FUNCTION1(env,loopControl,loopControl,i32,i32,i) {
usleep(50);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this all about? We shouldn't be sleeping. I think this entire intrinsic can be removed.

return i < 40;
}

wasm_interface& wasm_interface::get() {
static wasm_interface* wasm = nullptr;
if( !wasm )
Expand Down Expand Up @@ -279,6 +301,8 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
std::vector<Value> invokeArgs(1);
invokeArgs[0] = U32(bytes);

checktimeStart = std::chrono::system_clock::now();

auto result = Runtime::invokeFunction(alloc_function,invokeArgs);

return &memoryRef<char>( current_memory, result.i32 );
Expand Down Expand Up @@ -309,6 +333,8 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
memset( memstart + state.mem_end, 0, ((1<<16) - state.mem_end) );
memcpy( memstart, state.init_memory.data(), state.mem_end);

checktimeStart = std::chrono::system_clock::now();

Runtime::invokeFunction(call,args);
} catch( const Runtime::Exception& e ) {
edump((std::string(describeExceptionCause(e.cause))));
Expand All @@ -331,6 +357,8 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
return; /// if not found then it is a no-op
}

checktimeStart = std::chrono::system_clock::now();

const FunctionType* functionType = getFunctionType(apply);
FC_ASSERT( functionType->parameters.size() == 0 );

Expand Down Expand Up @@ -407,7 +435,7 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
{
wlog( "LOADING CODE" );
Serialization::MemoryInputStream stream((const U8*)recipient.code.data(),recipient.code.size());
WASM::serialize(stream,*state.module);
WASM::serializeWithInjection(stream,*state.module);

RootResolver rootResolver;
LinkResult linkResult = linkModule(*state.module,rootResolver);
Expand Down
5 changes: 3 additions & 2 deletions libraries/wasm-jit/Include/WASM/WASM.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Serialization { struct InputStream; struct OutputStream; }

namespace WASM
{
WEBASSEMBLY_API void serialize(Serialization::InputStream& stream,IR::Module& module);
WEBASSEMBLY_API void serialize(Serialization::OutputStream& stream,const IR::Module& module);
WEBASSEMBLY_API void serialize(Serialization::InputStream& stream,IR::Module& module);
WEBASSEMBLY_API void serializeWithInjection(Serialization::InputStream& stream,IR::Module& module);
WEBASSEMBLY_API void serialize(Serialization::OutputStream& stream,const IR::Module& module);
}
Loading