Skip to content

Commit

Permalink
Reduce usage of ContractReflectionInterface on DynamicContract
Browse files Browse the repository at this point in the history
  • Loading branch information
itamarcps committed Dec 21, 2023
1 parent 97686b5 commit 29a79c7
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 36 deletions.
10 changes: 5 additions & 5 deletions src/contract/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ namespace ABI {
struct FunctionTraits;

/// List the argument types of a function.
template <typename R, typename... Args, typename T>
struct FunctionTraits<R(T::*)(Args...)> {
template <typename... Args>
struct FunctionTraits<Args...> {
static std::string listArgumentTypes() {
std::string result;
((
Expand All @@ -708,11 +708,11 @@ namespace ABI {
struct Encoder;

/// Specialization for functions with arguments
template <typename R, typename... Args, typename T>
struct Encoder<R(T::*)(Args...)> {
template <typename... Args>
struct Encoder<Args...> {
static Functor encode(const std::string& funcSignature) {
std::string fullSignature = funcSignature;
fullSignature += "(" + FunctionTraits<R(T::*)(Args...)>::listArgumentTypes() + ")";
fullSignature += "(" + FunctionTraits<Args...>::listArgumentTypes() + ")";
return Functor(Utils::sha3(Utils::create_view_span(fullSignature)).view_const(0, 4));
}
};
Expand Down
38 changes: 7 additions & 31 deletions src/contract/dynamiccontract.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ class DynamicContract : public BaseContract {
template <typename R, typename T> void registerMemberFunction(
const std::string& funcSignature, R(T::*memFunc)() const, T* instance
) {
bool hasArgs = ContractReflectionInterface::methodHasArguments<decltype(*instance)>(funcSignature);
std::string methodMutability = ContractReflectionInterface::getMethodMutability<decltype(*instance)>(funcSignature);
if (hasArgs) throw std::runtime_error("Invalid function signature.");

std::string functStr = funcSignature + "()";

const std::unordered_map<std::string, std::function<void()>> mutabilityActions = {
Expand Down Expand Up @@ -127,10 +124,7 @@ class DynamicContract : public BaseContract {
template <typename R, typename T> void registerMemberFunction(
const std::string& funcSignature, R(T::*memFunc)(), T* instance
) {
bool hasArgs = ContractReflectionInterface::methodHasArguments<decltype(*instance)>(funcSignature);
std::string methodMutability = ContractReflectionInterface::getMethodMutability<decltype(*instance)>(funcSignature);
if (hasArgs) throw std::runtime_error("Invalid function signature.");

std::string functStr = funcSignature + "()";

const std::unordered_map<std::string, std::function<void()>> mutabilityActions = {
Expand Down Expand Up @@ -166,17 +160,8 @@ class DynamicContract : public BaseContract {
template <typename R, typename... Args, typename T> void registerMemberFunction(
const std::string& funcSignature, R(T::*memFunc)(Args...), T* instance
) {
std::vector<std::string> args = ContractReflectionInterface::getMethodArgumentsTypesString<decltype(*instance)>(funcSignature);
std::string methodMutability = ContractReflectionInterface::getMethodMutability<decltype(*instance)>(funcSignature);
std::ostringstream fullSignatureStream;
fullSignatureStream << funcSignature << "(";
if (!args.empty()) {
std::copy(args.begin(), args.end() - 1, std::ostream_iterator<std::string>(fullSignatureStream, ","));
fullSignatureStream << args.back();
}
fullSignatureStream << ")";

std::string fullSignature = fullSignatureStream.str();
Functor functor = ABI::FunctorEncoder::Encoder<Args...>::encode(funcSignature);

auto registrationFunc = [this, instance, memFunc, funcSignature](const ethCallInfo &callInfo) {
using DecayedArgsTuple = std::tuple<std::decay_t<Args>...>;
Expand All @@ -189,9 +174,9 @@ class DynamicContract : public BaseContract {
if (methodMutability == "view") {
throw std::runtime_error("View must be const because it does not modify the state.");
} else if (methodMutability == "nonpayable") {
this->registerFunction(Utils::sha3(Utils::create_view_span(fullSignature)).view_const(0, 4), registrationFunc);
this->registerFunction(functor, registrationFunc);
} else if (methodMutability == "payable") {
this->registerPayableFunction(Utils::sha3(Utils::create_view_span(fullSignature)).view_const(0, 4), registrationFunc);
this->registerPayableFunction(functor, registrationFunc);
} else {
throw std::runtime_error("Invalid function signature.");
}
Expand All @@ -206,17 +191,8 @@ class DynamicContract : public BaseContract {
template <typename R, typename... Args, typename T> void registerMemberFunction(
const std::string& funcSignature, R(T::*memFunc)(Args...) const, T* instance
) {
std::vector<std::string> args = ContractReflectionInterface::getMethodArgumentsTypesString<decltype(*instance)>(funcSignature);
std::string methodMutability = ContractReflectionInterface::getMethodMutability<decltype(*instance)>(funcSignature);
std::ostringstream fullSignatureStream;
fullSignatureStream << funcSignature << "(";
if (!args.empty()) {
std::copy(args.begin(), args.end() - 1, std::ostream_iterator<std::string>(fullSignatureStream, ","));
fullSignatureStream << args.back();
}
fullSignatureStream << ")";

std::string fullSignature = fullSignatureStream.str();
Functor functor = ABI::FunctorEncoder::Encoder<Args...>::encode(funcSignature);

auto registrationFunc = [this, instance, memFunc, funcSignature](const ethCallInfo &callInfo) -> Bytes {
using ReturnType = decltype((instance->*memFunc)(std::declval<Args>()...));
Expand All @@ -234,11 +210,11 @@ class DynamicContract : public BaseContract {
};

if (methodMutability == "view") {
this->registerViewFunction(Utils::sha3(Utils::create_view_span(fullSignature)).view_const(0, 4), registrationFunc);
this->registerViewFunction(functor, registrationFunc);
} else if (methodMutability == "nonpayable") {
this->registerFunction(Utils::sha3(Utils::create_view_span(fullSignature)).view_const(0, 4), registrationFunc);
this->registerFunction(functor, registrationFunc);
} else if (methodMutability == "payable") {
this->registerPayableFunction(Utils::sha3(Utils::create_view_span(fullSignature)).view_const(0, 4), registrationFunc);
this->registerPayableFunction(functor, registrationFunc);
} else {
throw std::runtime_error("Invalid function signature.");
}
Expand Down

0 comments on commit 29a79c7

Please sign in to comment.