diff --git a/.gitignore b/.gitignore index 259148fa1..ce341760f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ *.exe *.out *.app + +build/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bf8cab8d..3061de8f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.1.1) +project(eosio_contracts VERSION 1.2.0) + +set(EOSIO_DEPENDENCY "1.1") +set(EOSIO_WASMSDK_DEPENDENCY "1.1") if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") @@ -7,22 +10,26 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") else() set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() -if(CXX_COMPILER STREQUAL "" OR NOT CXX_COMPILER) - set(CXX_COMPILER ${CMAKE_CXX_COMPILER}) -endif() -if(EOSIO_INSTALL_PREFIX STREQUAL "" OR NOT EOSIO_INSTALL_PREFIX) - set(EOSIO_INSTALL_PREFIX "/usr/local") +if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) + set(EOSIO_ROOT "/usr/local/eosio") endif() -# if no wasm root is given use default path -if(WASM_ROOT STREQUAL "" OR NOT WASM_ROOT) - set(WASM_ROOT ${CMAKE_INSTALL_PREFIX}) +if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) + set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk") endif() -list(APPEND CMAKE_MODULE_PATH ${WASM_ROOT}/lib/cmake) +list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) include(EosioWasmToolchain) +### Check the version of wasmsdk +string(FIND "${EOSIO_WASMSDK_VERSION}" "${EOSIO_WASMSDK_DEPENDENCY}" output) + +if (NOT "${output}" EQUAL 0) + message(FATAL_ERROR "Incorrect EOSIO.WasmSDK version, please use version ${EOSIO_WASMSDK_DEPENDENCY}.x") +endif() + +include_directories(AFTER ${BOOST_ROOT}/include) add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) add_subdirectory(eosio.system) diff --git a/README.md b/README.md index 883c887f7..b27fdc4b8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.1.1 +## Version : 1.2.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) -* [eosio.wasmsdk v1.0.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.0.0) +* [eosio v1.1.2](https://github.com/eosio/eos/tree/v1.1.2) +* [eosio.wasmsdk v1.1.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.1.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 73ccd2d91..b7f9af503 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,10 +4,10 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} -DEOSIO_DEPENDENCY=${EOSIO_DEPENDENCY} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests - BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests + BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 TEST_COMMAND "" INSTALL_COMMAND "" diff --git a/build.sh b/build.sh index 815e9f277..5ef9e1ebf 100755 --- a/build.sh +++ b/build.sh @@ -5,58 +5,9 @@ printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' NC='\033[0m' -#if [ ! -d "/usr/local/eosio" ]; then -# printf "${RED}Error, please ensure that eosio is installed correctly!\n\n${NC}" -# exit -1 -#fi - -if [ ! -d "/usr/local/eosio.wasmsdk" ]; then - printf "${RED}Error, please ensure that eosio.wasmsdk is installed correctly!\n\n${NC}" - exit -1 -fi - -unamestr=`uname` -if [[ "${unamestr}" == 'Darwin' ]]; then - BOOST=/usr/local - CXX_COMPILER=g++ -else - BOOST=~/opt/boost - OS_NAME=$( cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI' ) - - case "$OS_NAME" in - "Amazon Linux AMI") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "CentOS Linux") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "elementary OS") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Fedora") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "Linux Mint") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Ubuntu") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - *) - printf "\\n\\tUnsupported Linux Distribution. Exiting now.\\n\\n" - exit 1 - esac -fi - CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ +cmake ../ make -j${CORES} popd &> /dev/null diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index c5dd83e7e..1741e7c97 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,4 +1,4 @@ -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_executable(eosio.msig.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm @@ -7,6 +7,6 @@ target_include_directories(eosio.msig.wasm set_target_properties(eosio.msig.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.msig/bin/eosio.msig/.gitignore b/eosio.msig/bin/eosio.msig/.gitignore deleted file mode 100644 index db5b01ccb..000000000 --- a/eosio.msig/bin/eosio.msig/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.msig.abi -eosio.msig.wasm diff --git a/eosio.msig/build.sh b/eosio.msig/build.sh deleted file mode 100755 index 13d28a8c9..000000000 --- a/eosio.msig/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.msig" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index f38dae570..b02d424e5 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(eosio.sudo.wasm set_target_properties(eosio.sudo.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE__CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.sudo/bin/eosio.sudo/.gitignore b/eosio.sudo/bin/eosio.sudo/.gitignore deleted file mode 100644 index 35898c3b5..000000000 --- a/eosio.sudo/bin/eosio.sudo/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.sudo.abi -eosio.sudo.wasm diff --git a/eosio.sudo/build.sh b/eosio.sudo/build.sh deleted file mode 100755 index 9892f2e87..000000000 --- a/eosio.sudo/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.sudo" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index b0bc44312..8b47085ee 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -6,8 +6,8 @@ target_include_directories(eosio.system.wasm set_target_properties(eosio.system.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.system/bin/eosio.system/.gitignore b/eosio.system/bin/eosio.system/.gitignore deleted file mode 100644 index 105891a48..000000000 --- a/eosio.system/bin/eosio.system/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.system.abi -eosio.system.wasm diff --git a/eosio.system/build.sh b/eosio.system/build.sh deleted file mode 100755 index f5028c698..000000000 --- a/eosio.system/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.system" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I../eosio.token/include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 276a61e71..659d8c815 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -67,9 +67,9 @@ namespace eosiosystem { struct eosio_global_state2 { eosio_global_state2(){} - uint16_t new_ram_per_block = 0; + uint16_t new_ram_per_block = 0; block_timestamp last_ram_increase; - block_timestamp last_block_num; + block_timestamp last_block_num; /* deprecated */ double reserved = 0; uint8_t revision = 0; ///< used to track version updates in the future. @@ -236,18 +236,19 @@ namespace eosiosystem { void bidname( account_name bidder, account_name newname, asset bid ); private: - void update_elected_producers( block_timestamp timestamp ); - void update_ram_supply(); - // Implementation details: - //defind in delegate_bandwidth.cpp + //defined in eosio.system.cpp + static eosio_global_state get_default_parameters(); + static block_timestamp current_block_time(); + void update_ram_supply(); + + //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); //defined in voting.hpp - static eosio_global_state get_default_parameters(); - + void update_elected_producers( block_timestamp timestamp ); void update_votes( const account_name voter, const account_name proxy, const std::vector& producers, bool voting ); // defined in voting.cpp diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 3b1599b7a..667a2c127 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -30,6 +30,7 @@ namespace eosiosystem { static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; + static constexpr int64_t ram_gift_bytes = 1400; struct user_resources { account_name owner; @@ -86,7 +87,7 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - + auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); @@ -152,7 +153,7 @@ namespace eosiosystem { res.ram_bytes += bytes_out; }); } - set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } @@ -179,7 +180,7 @@ namespace eosiosystem { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); }); - + eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above @@ -191,7 +192,7 @@ namespace eosiosystem { userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; }); - set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.ram),N(active)},{account,N(active)}}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); @@ -270,7 +271,10 @@ namespace eosiosystem { eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); - set_resource_limits( receiver, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver, &ram_bytes, &net, &cpu ); + + set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); @@ -286,8 +290,8 @@ namespace eosiosystem { auto net_balance = stake_net_delta; auto cpu_balance = stake_cpu_delta; bool need_deferred_trx = false; - - + + // net and cpu are same sign by assertions in delegatebw and undelegatebw // redundant assertion also at start of changebw to protect against misuse of changebw bool is_undelegating = (net_balance.amount + cpu_balance.amount ) < 0; diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 1f0b6a11f..4d7c5f501 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -46,6 +46,10 @@ namespace eosiosystem { return dp; } + block_timestamp system_contract::current_block_time() { + const static block_timestamp cbt{ time_point{ microseconds{ static_cast( current_time() ) } } }; + return cbt; + } system_contract::~system_contract() { _global.set( _gstate, _self ); @@ -73,10 +77,12 @@ namespace eosiosystem { } void system_contract::update_ram_supply() { - if( _gstate2.last_block_num <= _gstate2.last_ram_increase ) return; + auto cbt = current_block_time(); + + if( cbt <= _gstate2.last_ram_increase ) return; auto itr = _rammarket.find(S(4,RAMCORE)); - auto new_ram = (_gstate2.last_block_num.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; + auto new_ram = (cbt.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; _gstate.max_ram_size += new_ram; /** @@ -85,12 +91,12 @@ namespace eosiosystem { _rammarket.modify( itr, 0, [&]( auto& m ) { m.base.balance.amount += new_ram; }); - _gstate2.last_ram_increase = _gstate2.last_block_num; + _gstate2.last_ram_increase = cbt; } /** - * Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to - * a maximum rate of 3 TB per year. + * Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * a maximum rate of 3 TB per year. * * If update_ram_supply hasn't been called for the most recent block, then new ram will * be allocated at the old rate up to the present block before switching the rate. @@ -98,12 +104,8 @@ namespace eosiosystem { void system_contract::setramrate( uint16_t bytes_per_block ) { require_auth( _self ); + update_ram_supply(); _gstate2.new_ram_per_block = bytes_per_block; - if( _gstate2.last_ram_increase == block_timestamp() ) { - _gstate2.last_ram_increase = _gstate2.last_block_num; - } else { - update_ram_supply(); - } } void system_contract::setparams( const eosio::blockchain_parameters& params ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 84e2444ad..e661be740 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -21,6 +21,10 @@ namespace eosiosystem { using namespace eosio; require_auth(N(eosio)); + + // _gstate2.last_block_num is not used anywhere in the system contract code anymore. + // Although this field is deprecated, we will continue updating it for now until the last_block_num field + // is eventually completely removed, at which point this line can be removed. _gstate2.last_block_num = timestamp; /** until activated stake crosses this threshold no new rewards are paid */ diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index 39993201b..9ff728c36 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(eosio.token.wasm set_target_properties(eosio.token.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index b7352d365..ce5861f26 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -40,7 +40,7 @@ "base": "", "fields": [ {"name":"owner", "type":"account_name"}, - {"name":"symbol", "type":"symbol"}, + {"name":"symbol", "type":"symbol"} ] },{ "name": "account", diff --git a/eosio.token/bin/eosio.token/.gitignore b/eosio.token/bin/eosio.token/.gitignore deleted file mode 100644 index e55130074..000000000 --- a/eosio.token/bin/eosio.token/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.token.abi -eosio.token.wasm diff --git a/eosio.token/build.sh b/eosio.token/build.sh deleted file mode 100755 index 7394a4510..000000000 --- a/eosio.token/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.token" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2a22a3ea4..12b6d8f1b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,179 +1,21 @@ cmake_minimum_required( VERSION 3.5 ) -project( EOSIO_CONTRACTS_TESTS ) -set( VERSION_MAJOR 1 ) -set( VERSION_MINOR 0 ) -set( VERSION_PATCH 0 ) -enable_testing() +list(APPEND CMAKE_MODULE_PATH ${EOSIO_ROOT}/lib/cmake) +include(EosioTester) -find_package( Gperftools QUIET ) -if( GPERFTOOLS_FOUND ) - message( STATUS "Found gperftools; compiling tests with TCMalloc") - list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc ) +### check the version of EOSIO +string(FIND "${EOSIO_VERSION}" "${EOSIO_DEPENDENCY}" output) +if (NOT "${output}" EQUAL 0) + message(FATAL_ERROR "Incorrect EOSIO version, please use version ${EOSIO_DEPENDENCY}.x") endif() -find_package(LLVM 4.0 REQUIRED CONFIG) - -link_directories(${LLVM_LIBRARY_DIR}) - -set( CMAKE_CXX_STANDARD 14 ) -set( CMAKE_CXX_EXTENSIONS ON ) -set( CXX_STANDARD_REQUIRED ON ) - -if ( APPLE ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated-declarations" ) -else ( APPLE ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") -endif ( APPLE ) - -set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) -configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_SOURCE_DIR}/contracts.hpp) -find_package(Boost 1.67 REQUIRED COMPONENTS - date_time - filesystem - system - chrono - iostreams - date_time - unit_test_framework) - -file(GLOB UNIT_TESTS "*.cpp") - -find_library(libtester eosio_testing ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libchain eosio_chain ${EOSIO_INSTALL_PREFIX}/lib) -if ( "${CMAKE_BUILD_TYPE}" EQUAL "Debug" ) - find_library(libfc fc_debug ${EOSIO_INSTALL_PREFIX}/lib) -else() - find_library(libfc fc ${EOSIO_INSTALL_PREFIX}/lib) -endif() -find_library(libbinaryen binaryen ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libwasm WASM ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libwast WAST ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libir IR ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libplatform Platform ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liblogging Logging ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libruntime Runtime ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libsoftfloat softfloat ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liboscrypto crypto ${OPENSSL_INSTALL_PREFIX}/lib) -find_library(libosssl ssl ${OPENSSL_INSTALL_PREFIX}/lib) -find_library(libchainbase chainbase ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libbuiltins builtins ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) - -add_executable( unit_test ${UNIT_TESTS} ) -target_link_libraries( unit_test - ${LLVM} - ${libtester} - ${libchain} - ${libfc} - ${libbinaryen} - ${libwast} - ${libwasm} - ${libruntime} - ${libplatform} - ${libir} - ${libsoftfloat} - ${liboscrypto} - ${libosssl} - ${liblogging} - ${libchainbase} - ${libbuiltins} - ${libsecp256k1} - - LLVMX86Disassembler - LLVMX86AsmParser - LLVMX86AsmPrinter - LLVMX86CodeGen - - LLVMSelectionDAG - - LLVMDebugInfoDWARF - LLVMAsmPrinter - LLVMMCParser - LLVMX86Info - - LLVMOrcJIT - LLVMExecutionEngine - - LLVMCodeGen - LLVMScalarOpts - LLVMTransformUtils - - LLVMipo - LLVMAnalysis - LLVMTarget - LLVMMC - LLVMCore - LLVMSupport - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${Boost_CHRONO_LIBRARY} - ${Boost_IOSTREAMS_LIBRARY} - ${Boost_DATE_TIME_LIBRARY} - ${PLATFORM_SPECIFIC_LIBS} - ) -target_include_directories( unit_test PUBLIC - ${Boost_INCLUDE_DIRS} - ${OPENSSL_INSTALL_PREFIX}/include - ${EOSIO_INSTALL_PREFIX} - ${EOSIO_INSTALL_PREFIX}/include - ${EOSIO_INSTALL_PREFIX}/include/eosio/wasm-jit/Include - ${EOSIO_INSTALL_PREFIX}/include/eosio/softfloat/include - ${CMAKE_CURRENT_BINARY_DIR}/include ) - -#Manually run unit_test for all supported runtimes -#To run unit_test with all log from blockchain displayed, put --verbose after --, i.e. unit_test -- --verbose -add_test(NAME unit_test_binaryen COMMAND unit_test - --report_level=detailed --color_output -- --binaryen) -add_test(NAME unit_test_wavm COMMAND unit_test - --report_level=detailed --color_output --catch_system_errors=no -- --wavm) - -if(ENABLE_COVERAGE_TESTING) - - set(Coverage_NAME ${PROJECT_NAME}_ut_coverage) - - if(NOT LCOV_PATH) - message(FATAL_ERROR "lcov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT LLVMCOV_PATH) - message(FATAL_ERROR "llvm-cov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT GENHTML_PATH) - message(FATAL_ERROR "genhtml not found! Aborting...") - endif() # NOT GENHTML_PATH - - # no spaces allowed within tests list - set(ctest_tests 'unit_test_binaryen|unit_test_wavm') - set(ctest_exclude_tests '') - - # Setup target - add_custom_target(${Coverage_NAME} - - # Cleanup lcov - COMMAND ${LCOV_PATH} --directory . --zerocounters - - # Run tests - COMMAND ./tools/ctestwrapper.sh -R ${ctest_tests} -E ${ctest_exclude_tests} - - COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ./tools/llvm-gcov.sh --output-file ${Coverage_NAME}.info - - COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/fc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info +enable_testing() - COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info +configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contracts.hpp) - COMMAND if [ "$CI" != "true" ]\; then ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.info ${Coverage_NAME}_filtered.info ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info.cleaned\; fi +include_directories(${CMAKE_BINARY_DIR}) - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report. Report published in ./${Coverage_NAME}" - ) +file(GLOB UNIT_TESTS "*.cpp" "*.hpp") - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) -endif() +add_eosio_test( unit_test ${UNIT_TESTS} ) diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 1d91f506e..2db2153f1 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -4,18 +4,18 @@ namespace eosio { namespace testing { struct contracts { - static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi"); } + static std::vector system_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index ce01cc85d..0683a5523 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -36,7 +36,7 @@ class eosio_msig_tester : public tester { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, @@ -138,19 +138,19 @@ class eosio_msig_tester : public tester { action act; act.account = N(eosio.msig); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); */ } - transaction reqauth( account_name from, const vector& auths ); + transaction reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ); abi_serializer abi_ser; }; -transaction eosio_msig_tester::reqauth( account_name from, const vector& auths ) { +transaction eosio_msig_tester::reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ) { fc::variants v; for ( auto& level : auths ) { v.push_back(fc::mutable_variant_object() @@ -174,14 +174,14 @@ transaction eosio_msig_tester::reqauth( account_name from, const vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -304,7 +304,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); //try with not enough requested auth BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -345,7 +345,7 @@ BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -451,7 +451,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); // propose action push_action( N(alice), N(propose), mvo() @@ -562,7 +562,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); // propose action push_action( N(alice), N(propose), mvo() diff --git a/tests/eosio.sudo_tests.cpp b/tests/eosio.sudo_tests.cpp index 607b26772..8de7a93ff 100644 --- a/tests/eosio.sudo_tests.cpp +++ b/tests/eosio.sudo_tests.cpp @@ -77,7 +77,7 @@ class eosio_sudo_tester : public tester { const auto& accnt = control->db().get( N(eosio.sudo) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { produce_block(); @@ -134,7 +134,7 @@ transaction eosio_sudo_tester::sudo_exec( account_name executer, const transacti transaction trx2; set_transaction_headers(trx2, expiration); action act; - abi_serializer::from_variant( act_obj, act, get_resolver() ); + abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer_max_time ); trx2.actions.push_back( std::move(act) ); return trx2; } @@ -155,7 +155,7 @@ transaction eosio_sudo_tester::reqauth( account_name from, const vectordb().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi); + token_abi_ser.set_abi(abi, abi_serializer_max_time); } create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); @@ -63,7 +63,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } produce_blocks(); @@ -219,7 +219,7 @@ class eosio_system_tester : public TESTER { action act; act.account = config::system_account_name; act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); } @@ -320,22 +320,22 @@ class eosio_system_tester : public TESTER { asset get_balance( const account_name& act ) { vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data)["balance"].as(); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data ); + return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); } void create_currency( name contract, name manager, asset maxsupply ) { @@ -375,7 +375,7 @@ class eosio_system_tester : public TESTER { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } asset get_token_supply() { @@ -385,17 +385,17 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer_max_time ); } fc::variant get_global_state2() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer_max_time ); } fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer_max_time ); } abi_serializer initialize_multisig() { @@ -410,7 +410,7 @@ class eosio_system_tester : public TESTER { ("account", "eosio.msig") ("is_priv", 1) ); - + set_code( N(eosio.msig), contracts::msig_wasm() ); set_abi( N(eosio.msig), contracts::msig_abi().data() ); @@ -418,13 +418,11 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi); + msig_abi_ser.set_abi(msig_abi, abi_serializer_max_time); } return msig_abi_ser; } - //helper function - vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain transfer( "eosio", "alice1111111", core_from_string("650000000.0000"), "eosio" ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b8f5380da..06bae27d4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -1696,7 +1695,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -1735,7 +1734,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2471,7 +2470,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -2507,7 +2506,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2609,12 +2608,15 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); produce_blocks(3); BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - const uint16_t rate = 1000; + uint16_t rate = 1000; BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); BOOST_REQUIRE_EQUAL( rate, get_global_state2()["new_ram_per_block"].as() ); - // last time update_ram_supply called is in buyram, num of blocks since then is 1 + 3 = 4 + // last time update_ram_supply called is in buyram, num of blocks since then to + // the block that includes the setramrate action is 1 + 3 = 4. + // However, those 4 blocks were accumulating at a rate of 0, so the max_ram_size should not have changed. + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + // But with additional blocks, it should start accumulating at the new rate. uint64_t cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - BOOST_REQUIRE_EQUAL( init_max_ram_size + 4 * rate, get_global_state()["max_ram_size"].as_uint64() ); produce_blocks(10); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * rate, get_global_state()["max_ram_size"].as_uint64() ); @@ -2630,9 +2632,19 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); - + + cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); + produce_blocks(10); + uint16_t old_rate = rate; + rate = 5000; + BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate, get_global_state()["max_ram_size"].as_uint64() ); + produce_blocks(5); + BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); + } FC_LOG_AND_RETHROW() - + BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); @@ -2654,7 +2666,7 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { auto rlm = control->get_resource_limits_manager(); auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - //std::cout << "Sellram" << std::endl; + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 2048 ) ); //make sure that ram was billed to alice, not to eosio.ram @@ -2663,30 +2675,49 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_SUITE_END() +BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { + active_and_vote_producers(); -void translate_fc_exception(const fc::exception &e) { - std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; - BOOST_TEST_FAIL("Caught Unexpected Exception"); -} + auto rlm = control->get_resource_limits_manager(); + int64_t ram_bytes_orig, net_weight, cpu_weight; + rlm.get_account_limits( N(alice1111111), ram_bytes_orig, net_weight, cpu_weight ); -boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { - // Turn off blockchain logging if no --verbose parameter is not added - // To have verbose enabled, call "tests/chain_test -- --verbose" - bool is_verbose = false; - std::string verbose_arg = "--verbose"; - for (int i = 0; i < argc; i++) { - if (verbose_arg == argv[i]) { - is_verbose = true; - break; - } - } - if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + /* + * It seems impossible to write this test, because buyrambytes action doesn't give you exact amount of bytes requested + * + //check that it's possible to create account bying required_bytes(2724) + userres table(112) + userres row(160) - ram_gift_bytes(1400) + create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 ); + + //check that one byte less is not enough + BOOST_REQUIRE_THROW( create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 - 1 ), + ram_usage_exceeded ); + */ - // Register fc::exception translator - boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); + //check that stake/unstake keeps the gift + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + int64_t ram_bytes_after_stake; + rlm.get_account_limits( N(alice1111111), ram_bytes_after_stake, net_weight, cpu_weight ); + BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); - std::srand(time(NULL)); - std::cout << "Random number generator seeded to " << time(NULL) << std::endl; - return nullptr; -} + BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_from_string("20.0000"), core_from_string("10.0000") ) ); + int64_t ram_bytes_after_unstake; + rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); + BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); + + uint64_t ram_gift = 1400; + + int64_t ram_bytes; + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("1000.0000") ) ); + rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); + auto userres = get_total_stake( N(alice1111111) ); + BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 1024 ) ); + rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); + userres = get_total_stake( N(alice1111111) ); + BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); + +} FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 093d8d0f1..e77ddf70b 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -33,7 +33,7 @@ class eosio_token_tester : public tester { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { @@ -42,7 +42,7 @@ class eosio_token_tester : public tester { action act; act.account = N(eosio.token); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data,abi_serializer_max_time ); return base_tester::push_action( std::move(act), uint64_t(signer)); } @@ -52,7 +52,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } fc::variant get_account( account_name acc, const string& symbolname) @@ -60,7 +60,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); } action_result create( account_name issuer, diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 000000000..2c658f31a --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eosio.system_tester.hpp" + +using namespace eosio_system; +#define BOOST_TEST_STATIC_LINK + +void translate_fc_exception(const fc::exception &e) { + std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; + BOOST_TEST_FAIL("Caught Unexpected Exception"); +} + +boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { + // Turn off blockchain logging if no --verbose parameter is not added + // To have verbose enabled, call "tests/chain_test -- --verbose" + bool is_verbose = false; + std::string verbose_arg = "--verbose"; + for (int i = 0; i < argc; i++) { + if (verbose_arg == argv[i]) { + is_verbose = true; + break; + } + } + if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + + // Register fc::exception translator + boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); + + std::srand(time(NULL)); + std::cout << "Random number generator seeded to " << time(NULL) << std::endl; + return nullptr; +}