common.h 5.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
    Copyright (C) 2019-Present SKALE Labs

    This file is part of sgxwallet.

    sgxwallet is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    sgxwallet is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with sgxwallet.  If not, see <https://www.gnu.org/licenses/>.

kladko's avatar
kladko committed
19
    @file common.h
20 21 22 23
    @author Stan Kladko
    @date 2020
*/

24 25 26 27 28 29 30 31 32 33

#ifndef SGXWALLET_COMMON_H
#define SGXWALLET_COMMON_H

using namespace std;

#include <stdlib.h>
#include <iostream>
#include <map>
#include <memory>
34 35 36
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <string.h>
kladko's avatar
kladko committed
37
#include <vector>
kladko's avatar
kladko committed
38
#include <json/value.h>
39
#include <boost/throw_exception.hpp>
kladko's avatar
kladko committed
40
#include <gmp.h>
kladko's avatar
kladko committed
41 42 43 44 45 46 47
#include <thread>
#include <functional>
#include <atomic>
#include <condition_variable>
#include <mutex>


kladko's avatar
kladko committed
48
#include "secure_enclave/Verify.h"
kladko's avatar
kladko committed
49
#include "InvalidStateException.h"
kladko's avatar
kladko committed
50
#include "SGXException.h"
kladko's avatar
kladko committed
51

kladko's avatar
kladko committed
52 53
#define SAFE_FREE(__POINTER__) {if (__POINTER__) {free(__POINTER__); __POINTER__ = NULL;}}

kladko's avatar
kladko committed
54 55 56 57 58 59 60 61 62 63 64
inline std::string className(const std::string &prettyFunction) {
    size_t colons = prettyFunction.find("::");
    if (colons == std::string::npos)
        return "::";
    size_t begin = prettyFunction.substr(0, colons).rfind(" ") + 1;
    size_t end = colons - begin;

    return prettyFunction.substr(begin, end);
}

#define __CLASS_NAME__ className( __PRETTY_FUNCTION__ )
65

66 67
#include <execinfo.h>

kladko's avatar
kladko committed
68
inline void print_stack(int _line) {
69 70 71 72 73 74 75
    void *array[10];
    size_t size;

    // get void*'s for all entries on the stack
    size = backtrace(array, 10);

    // print out all the frames to stderr
kladko's avatar
kladko committed
76
    fprintf(stderr, "Backtrace on line %d:   \n", _line);
77 78 79
    backtrace_symbols_fd(array, size, STDERR_FILENO);
}

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
inline int parseLine(char* line) {
    // This assumes that a digit will be found and the line ends in " Kb".
    int i = strlen(line);
    const char* p = line;
    while (*p <'0' || *p > '9') p++;
    line[i-3] = '\0';
    i = atoi(p);
    return i;
}

inline int getValue() { //Note: this value is in KB!
    FILE* file = fopen("/proc/self/status", "r");
    int result = -1;
    char line[128];

    while (fgets(line, 128, file) != NULL){
        if (strncmp(line, "VmRSS:", 6) == 0){
            result = parseLine(line);
            break;
        }
    }
    fclose(file);
    return result;
}

105 106
#define CHECK_STATE(_EXPRESSION_) \
    if (!(_EXPRESSION_)) { \
Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
107
        auto __msg__ = std::string("State check failed::") + #_EXPRESSION_ +  " " + std::string(__FILE__) + ":" + std::to_string(__LINE__); \
kladko's avatar
kladko committed
108
        \
kladko's avatar
kladko committed
109
        BOOST_THROW_EXCEPTION(SGXException(-100, string(__CLASS_NAME__) +  ":" + __msg__));}
kladko's avatar
kladko committed
110

kladko's avatar
kladko committed
111 112 113 114 115 116
#define CHECK_STATE2(_EXPRESSION_, __STATUS__) \
    if (!(_EXPRESSION_)) { \
        auto __msg__ = std::string("State check failed::") + #_EXPRESSION_ +  " " + std::string(__FILE__) + ":" + std::to_string(__LINE__); \
        \
        BOOST_THROW_EXCEPTION(SGXException(__STATUS__, string(__CLASS_NAME__) +  ":" + __msg__));}

117

kladko's avatar
kladko committed
118 119 120 121 122 123
#define HANDLE_TRUSTED_FUNCTION_ERROR(__STATUS__, __ERR_STATUS__, __ERR_MSG__) \
if (__STATUS__ != SGX_SUCCESS) { \
string __ERR_STRING__ = string("SGX enclave call to ") + \
                   __FUNCTION__  +  " failed with status:" \
                   + to_string(__STATUS__) + \
                   " Err message:" + __ERR_MSG__; \
124
BOOST_THROW_EXCEPTION(SGXException(-102, string(__ERR_STRING__))); \
kladko's avatar
kladko committed
125 126 127 128 129 130 131 132 133 134 135
}\
\
if (__ERR_STATUS__ != 0) {\
string __ERR_STRING__ = string("SGX enclave call to ") +\
                   __FUNCTION__  +  " failed with errStatus:" +                \
                     to_string(__ERR_STATUS__) + \
                   " Err message:" + __ERR_MSG__;\
BOOST_THROW_EXCEPTION(runtime_error(__ERR_STRING__)); \
}


kladko's avatar
kladko committed
136 137 138
#define SAFE_CHAR_BUF(__X__, __Y__)  ;char __X__ [ __Y__ ]; memset(__X__, 0, __Y__);
#define SAFE_UINT8_BUF(__X__, __Y__)  ;uint8_t __X__ [ __Y__ ]; memset(__X__, 0, __Y__);

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
// Copy from libconsensus

inline string exec( const char* cmd ) {
    CHECK_STATE( cmd );
    std::array< char, 128 > buffer;
    std::string result;
    std::unique_ptr< FILE, decltype( &pclose ) > pipe( popen( cmd, "r" ), pclose );
    if ( !pipe ) {
        BOOST_THROW_EXCEPTION( std::runtime_error( "popen() failed!" ) );
    }
    while ( fgets( buffer.data(), buffer.size(), pipe.get() ) != nullptr ) {
        result += buffer.data();
    }
    return result;
}

kladko's avatar
kladko committed
155 156
#include <shared_mutex>

Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
157
extern std::shared_timed_mutex sgxInitMutex;
kladko's avatar
kladko committed
158 159
extern uint64_t initTime;

160
#define LOCK(__X__) std::lock_guard<std::recursive_mutex> __LOCK__(__X__);
kladko's avatar
kladko committed
161 162 163
#define READ_LOCK(__X__) std::shared_lock<std::shared_timed_mutex> __LOCK__(__X__);
#define WRITE_LOCK(__X__) std::unique_lock<std::shared_timed_mutex> __LOCK__(__X__);

164

165
#endif //SGXWALLET_COMMON_H