提交 739822ea 编写于 作者: A arhag

Merge branch 'master' into arhag

......@@ -27,7 +27,7 @@ before_install:
- |
mkdir ext && cd ext
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
brew install boost openssl llvm@4 gmp gettext ninja mongodb mongo-c-driver
brew install boost openssl llvm@4 gmp gettext ninja mongodb mongo-c-driver python3
brew link gettext --force
brew services start mongodb
WASM_BRANCH=macos
......
......@@ -34,7 +34,6 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
set(BUILD_DOXYGEN FALSE CACHE BOOL "Build doxygen documentation on every make")
set(BUILD_MONGO_DB_PLUGIN FALSE CACHE BOOL "Build mongo database plugin")
......
......@@ -59,7 +59,8 @@ if( NOT ("${WASM_CLANG}" STREQUAL "" OR "${WASM_LLC}" STREQUAL "" OR "${WASM_LLV
endif()
macro(compile_wast)
cmake_parse_arguments(ARG "" "TARGET" "SOURCE_FILES;INCLUDE_FOLDERS" ${ARGN})
#read arguments include ones that we don't since arguments get forwared "as is" and we don't want to threat unknown argument names as values
cmake_parse_arguments(ARG "NOWARNINGS" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS;SYSTEM_INCLUDE_FOLDERS;LIBRARIES" ${ARGN})
set(target ${ARG_TARGET})
# NOTE: Setting SOURCE_FILE and looping over it to avoid cmake issue with compilation ${target}.bc's rule colliding with
......@@ -106,10 +107,28 @@ macro(compile_wast)
-nostdlib -nostdlibinc -fno-threadsafe-statics -fno-rtti -fno-exceptions
-c ${infile} -o ${outfile}.bc
)
if (${ARG_NOWARNINGS})
list(APPEND WASM_COMMAND -Wno-everything)
else()
list(APPEND WASM_COMMAND -Weverything -Wno-c++98-compat -Wno-old-style-cast -Wno-vla -Wno-vla-extension -Wno-c++98-compat-pedantic
-Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-packed -Wno-padded -Wno-c99-extensions)
endif()
foreach(folder ${ARG_INCLUDE_FOLDERS})
list(APPEND WASM_COMMAND -I ${folder})
endforeach()
if ("${ARG_SYSTEM_INCLUDE_FOLDERS}" STREQUAL "")
set (ARG_SYSTEM_INCLUDE_FOLDERS ${DEFAULT_SYSTEM_INCLUDE_FOLDERS})
endif()
foreach(folder ${ARG_SYSTEM_INCLUDE_FOLDERS})
list(APPEND WASM_COMMAND -isystem ${folder})
endforeach()
foreach(folder ${ARG_SYSTEM_INCLUDE_FOLDERS})
list(APPEND WASM_COMMAND -isystem ${folder})
endforeach()
add_custom_command(OUTPUT ${outfile}.bc
DEPENDS ${infile}
COMMAND ${WASM_COMMAND}
......@@ -128,9 +147,9 @@ macro(compile_wast)
endmacro(compile_wast)
macro(add_wast_library)
cmake_parse_arguments(ARG "" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS" ${ARGN})
cmake_parse_arguments(ARG "NOWARNINGS" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS;SYSTEM_INCLUDE_FOLDERS" ${ARGN})
set(target ${ARG_TARGET})
compile_wast(TARGET ${ARG_TARGET} SOURCE_FILES ${ARG_SOURCE_FILES} INCLUDE_FOLDERS ${ARG_INCLUDE_FOLDERS})
compile_wast(${ARGV})
get_filename_component("${ARG_TARGET}_BC_FILENAME" "${ARG_DESTINATION_FOLDER}/${ARG_TARGET}.bc" ABSOLUTE CACHE)
add_custom_target(${target} ALL DEPENDS ${${ARG_TARGET}_BC_FILENAME})
......@@ -146,11 +165,11 @@ macro(add_wast_library)
endmacro(add_wast_library)
macro(add_wast_executable)
cmake_parse_arguments(ARG "" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS;LIBRARIES" ${ARGN})
cmake_parse_arguments(ARG "NOWARNINGS" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS;SYSTEM_INCLUDE_FOLDERS;LIBRARIES" ${ARGN})
set(target ${ARG_TARGET})
set(DESTINATION_FOLDER ${ARG_DESTINATION_FOLDER})
compile_wast(TARGET ${ARG_TARGET} SOURCE_FILES ${ARG_SOURCE_FILES} INCLUDE_FOLDERS ${ARG_INCLUDE_FOLDERS})
compile_wast(${ARGV})
foreach(lib ${ARG_LIBRARIES})
list(APPEND LIBRARIES ${${lib}_BC_FILENAME})
......
pipeline {
agent any
stages {
stage('Build') {
parallel {
stage('Ubuntu') {
steps {
sh '''
. $HOME/.bash_profile
./eosio_build.sh
'''
}
}
stage('MacOS') {
steps {
sh '''
. $HOME/.bash_profile
echo "Darwin build coming soon..."
'''
}
}
stage('Fedora') {
steps {
sh '''
. $HOME/.bash_profile
echo "Fedora build coming soon..."
'''
}
}
}
}
stage('Tests') {
parallel {
stage('Ubuntu') {
steps {
sh '''
. $HOME/.bash_profile
export EOSLIB=$(pwd)/contracts
cd build
printf "Waiting for testing to be available..."
while /usr/bin/pgrep -x ctest > /dev/null; do sleep 1; done
echo "OK!"
ctest --output-on-failure
'''
}
}
stage('MacOS') {
steps {
sh '''
. $HOME/.bash_profile
echo "Darwin tests coming soon..."
'''
}
}
stage('Fedora') {
steps {
sh '''
. $HOME/.bash_profile
echo "Fedora tests coming soon..."
'''
}
}
}
}
}
post {
always {
cleanWs()
}
}
}
\ No newline at end of file
......@@ -14,9 +14,10 @@ The public testnet described in the [wiki](https://github.com/EOSIO/eos/wiki/Tes
### Supported Operating Systems
EOS.IO currently supports the following operating systems:
1. Ubuntu 16.04 and higher (Ubuntu 16.10 recommended).
2. MacOS Darwin 10.12 and higher (MacOS 10.13.x recommended).
3. Fedora 25 and higher (Fedora 27 recommended).
1. Amazon 2017.09 and higher.
2. Fedora 25 and higher (Fedora 27 recommended).
3. Ubuntu 16.04 and higher (Ubuntu 16.10 recommended).
4. MacOS Darwin 10.12 and higher (MacOS 10.13.x recommended).
# Resources
1. [EOS.IO Website](https://eos.io)
......@@ -33,8 +34,8 @@ EOS.IO currently supports the following operating systems:
1. [Getting Started](#gettingstarted)
2. [Setting up a build/development environment](#setup)
1. [Automated build script](#autobuild)
1. [Clean install Linux (Ubuntu & Fedora) for a local testnet](#autoubuntulocal)
2. [Clean install Linux (Ubuntu & Fedora) for the public testnet](#autoubuntupublic)
1. [Clean install Linux (Amazon, Fedora, & Ubuntu) for a local testnet](#autoubuntulocal)
2. [Clean install Linux (Amazon, Fedora, & Ubuntu) for the public testnet](#autoubuntupublic)
3. [MacOS for a local testnet](#automaclocal)
4. [MacOS for the public testnet](#automacpublic)
3. [Building EOS and running a node](#runanode)
......@@ -54,9 +55,10 @@ EOS.IO currently supports the following operating systems:
7. [Doxygen documentation](#doxygen)
8. [Running EOS in Docker](#docker)
9. [Manual installation of the dependencies](#manualdep)
1. [Clean install Ubuntu 16.04 and higher](#ubuntu)
2. [MacOS Sierra 10.12 and higher](#macos)
3. [Fedora 25 and higher](#fedora)
1. [Clean install Amazon 2017.09 and higher](#manualdepamazon)
2. [Clean install Fedora 25 and higher](#manualdepfedora)
3. [Clean install Ubuntu 16.04 and higher](#manualdepubuntu)
4. [Clean install MacOS Sierra 10.12 and higher](#manualdepmacos)
<a name="gettingstarted"></a>
## Getting Started
......@@ -69,12 +71,13 @@ The following instructions detail the process of getting the software, building
### Automated build script
Supported Operating Systems:
1. Ubuntu 16.04 and higher.
2. MacOS Darwin 10.12 and higher.
3. Fedora 25 and higher.
1. Amazon 2017.09 and higher.
2. Fedora 25 and higher (Fedora 27 recommended).
3. Ubuntu 16.04 and higher (Ubuntu 16.10 recommended).
4. MacOS Darwin 10.12 and higher (MacOS 10.13.x recommended).
For Ubuntu, MacOS and Fedora there is an automated build script that can install all dependencies and builds EOS.
We are working on supporting Centos, Amazon Linux & Red Hat in future releases.
For Amazon, Fedora, Ubuntu & MacOS there is an automated build script that can install all dependencies and builds EOS.
We are working on supporting other Linux/Unix distributions in future releases.
It is called eosio_build.sh
......@@ -89,7 +92,7 @@ Choose whether you will be building for a local testnet or for the public testne
We strongly recommend following the instructions for building the public testnet version for [Ubuntu](#autoubuntupublic) or [Mac OS X](#automacpublic). `master` is in pieces on the garage floor while we rebuild this hotrod. This notice will be removed when `master` is usable again. Your patience is appreciated.
<a name="autoubuntulocal"></a>
#### :no_entry: Clean install Linux (Ubuntu & Fedora) for a local testnet :no_entry:
#### :no_entry: Clean install Linux (Amazon, Fedora & Ubuntu) for a local testnet :no_entry:
```bash
git clone https://github.com/eosio/eos --recursive
......@@ -107,7 +110,7 @@ sudo make install
Now you can proceed to the next step - [Creating and launching a single-node testnet](#singlenode)
<a name="autoubuntupublic"></a>
#### Clean install Linux (Ubuntu & Fedora) for the public testnet
#### Clean install Linux (Amazon, Fedora & Ubuntu) for the public testnet
```bash
git clone https://github.com/eosio/eos --recursive
......@@ -567,33 +570,31 @@ Dependencies:
* [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git)
* [binaryen](https://github.com/WebAssembly/binaryen.git)
<a name="ubuntu"></a>
### Clean install Ubuntu 16.10
<a name="manualdepamazon"></a>
### Clean install Amazon 2017.09 and higher
Install the development toolkit:
```bash
sudo apt-get update
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-get install clang-4.0 lldb-4.0 libclang-4.0-dev cmake make \
libbz2-dev libssl-dev libgmp3-dev \
autotools-dev build-essential \
libbz2-dev libicu-dev python-dev \
autoconf libtool git
sudo yum update
sudo yum install git gcc72.x86_64 gcc72-c++.x86_64 autoconf automake libtool make bzip2 \
bzip2-devel.x86_64 openssl-devel.x86_64 gmp.x86_64 gmp-devel.x86_64 \
libstdc++72.x86_64 python27-devel.x86_64 libedit-devel.x86_64 \
ncurses-devel.x86_64 swig.x86_64 gettext-devel.x86_64
```
Install Boost 1.66:
```bash
cd ~
wget -c 'https://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_66_0.tar.bz2/download' -O boost_1.64.0.tar.bz2
tar xjf boost_1.66.0.tar.bz2
cd boost_1_66_0/
curl -L https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.bz2 > boost_1.66.0.tar.bz2
tar xf boost_1.66.0.tar.bz2
echo "export BOOST_ROOT=$HOME/boost_1_66_0" >> ~/.bash_profile
source ~/.bash_profile
cd boost_1_66_0/
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
source ~/.bash_profile
```
Install [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git):
......@@ -604,7 +605,7 @@ git clone https://github.com/cryptonomex/secp256k1-zkp.git
cd secp256k1-zkp
./autogen.sh
./configure
make
make -j$( nproc )
sudo make install
```
......@@ -638,8 +639,10 @@ cd ..
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
make -j4 install
make -j$( nproc )
make install
```
Add `WASM_LLVM_CONFIG` and `LLVM_DIR` to your `.bash_profile`:
```bash
......@@ -647,35 +650,33 @@ echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_p
echo "export LLVM_DIR=~/wasm-compiler/lib/cmake/llvm" >> ~/.bash_profile
source ~/.bash_profile
```
Your environment is set up. Now you can <a href="#runanode">build EOS and run a node</a>.
<a name="macos"></a>
### MacOS Sierra 10.12.6
macOS additional Dependencies:
* Brew
* Newest XCode
<a name="manualdepfedora"></a>
### Clean install Fedora 25 and higher
Upgrade your XCode to the newest version:
Install the development toolkit:
```bash
xcode-select --install
```
Install homebrew:
sudo yum update
sudo yum install git gcc.x86_64 gcc-c++.x86_64 autoconf automake libtool make cmake.x86_64 \
bzip2 bzip2-devel.x86_64 openssl-devel.x86_64 gmp-devel.x86_64 \
libstdc++-devel.x86_64 python3-devel.x86_64 libedit.x86_64 \
ncurses-devel.x86_64 swig.x86_64 gettext-devel.x86_64
```bash
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
Install the dependencies:
Install Boost 1.66:
```bash
brew update
brew install git automake libtool boost openssl llvm@4 gmp ninja gettext
brew link gettext --force
cd ~
curl -L https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.bz2 > boost_1.66.0.tar.bz2
tar xf boost_1.66.0.tar.bz2
echo "export BOOST_ROOT=$HOME/boost_1_66_0" >> ~/.bash_profile
source ~/.bash_profile
cd boost_1_66_0/
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
```
Install [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git):
......@@ -686,11 +687,11 @@ git clone https://github.com/cryptonomex/secp256k1-zkp.git
cd secp256k1-zkp
./autogen.sh
./configure
make
make -j$( nproc )
sudo make install
```
Install [binaryen v1.37.14](https://github.com/WebAssembly/binaryen.git):
To use the WASM compiler, EOS has an external dependency on [binaryen](https://github.com/WebAssembly/binaryen.git):
```bash
cd ~
......@@ -698,6 +699,7 @@ git clone https://github.com/WebAssembly/binaryen.git
cd ~/binaryen
git checkout tags/1.37.14
cmake . && make
```
Add `BINARYEN_ROOT` to your .bash_profile:
......@@ -707,7 +709,7 @@ echo "export BINARYEN_ROOT=~/binaryen" >> ~/.bash_profile
source ~/.bash_profile
```
Build LLVM and clang for WASM:
By default LLVM and clang do not include the WASM build target, so you will have to build it yourself:
```bash
mkdir ~/wasm-compiler
......@@ -726,35 +728,38 @@ Add `WASM_LLVM_CONFIG` and `LLVM_DIR` to your `.bash_profile`:
```bash
echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_profile
echo "export LLVM_DIR=/usr/local/Cellar/llvm@4/4.0.1/lib/cmake/llvm/" >> ~/.bash_profile
echo "export LLVM_DIR=~/wasm-compiler/lib/cmake/llvm" >> ~/.bash_profile
source ~/.bash_profile
```
Your environment is set up. Now you can <a href="#runanode">build EOS and run a node</a>.
<a name="fedora"></a>
### Clean install Fedora 25 and higher
<a name="manualdepubuntu"></a>
### Clean install Ubuntu 16.04 & Higher
Install the development toolkit:
```bash
sudo yum update
sudo yum install git gcc.x86_64 gcc-c++.x86_64 autoconf automake libtool make cmake.x86_64 \
bzip2 bzip2-devel.x86_64 openssl-devel.x86_64 gmp-devel.x86_64 \
libstdc++-devel.x86_64 python3-devel.x86_64 libedit.x86_64 \
ncurses-devel.x86_64 swig.x86_64 gettext-devel.x86_64
sudo apt-get update
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-get install clang-4.0 lldb-4.0 libclang-4.0-dev cmake make \
libbz2-dev libssl-dev libgmp3-dev \
autotools-dev build-essential \
libbz2-dev libicu-dev python-dev \
autoconf libtool git
```
Install Boost 1.66:
```bash
cd ~
curl -L https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.bz2 > boost_1.66.0.tar.bz2
tar xf boost_1.66.0.tar.bz2
wget -c 'https://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.bz2/download' -O boost_1.66.0.tar.bz2
tar xjf boost_1.66.0.tar.bz2
cd boost_1_66_0/
echo "export BOOST_ROOT=$HOME/boost_1_66_0" >> ~/.bash_profile
source ~/.bash_profile
cd boost_1_66_0/
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
source ~/.bash_profile
```
Install [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git):
......@@ -799,14 +804,96 @@ cd ..
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
make -j$( nproc ) install
make -j4 install
```
Add `WASM_LLVM_CONFIG` and `LLVM_DIR` to your `.bash_profile`:
```bash
echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_profile
echo "export LLVM_DIR=/usr/local/Cellar/llvm/4.0.1/lib/cmake/llvm" >> ~/.bash_profile
source ~/.bash_profile
```
Your environment is set up. Now you can <a href="#runanode">build EOS and run a node</a>.
<a name="manualdepmacos"></a>
### MacOS Sierra 10.12.6 & higher
macOS additional Dependencies:
* Brew
* Newest XCode
Upgrade your XCode to the newest version:
```bash
xcode-select --install
```
Install homebrew:
```bash
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
Install the dependencies:
```bash
brew update
brew install git automake libtool boost openssl llvm@4 gmp ninja gettext
brew link gettext --force
```
Install [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git):
```bash
cd ~
git clone https://github.com/cryptonomex/secp256k1-zkp.git
cd secp256k1-zkp
./autogen.sh
./configure
make -j$( sysctl -in machdep.cpu.core_count )
sudo make install
```
Install [binaryen v1.37.14](https://github.com/WebAssembly/binaryen.git):
```bash
cd ~
git clone https://github.com/WebAssembly/binaryen.git
cd ~/binaryen
git checkout tags/1.37.14
cmake . && make -j$( sysctl -in machdep.cpu.core_count )
```
Add `BINARYEN_ROOT` to your .bash_profile:
```bash
echo "export BINARYEN_ROOT=~/binaryen" >> ~/.bash_profile
source ~/.bash_profile
```
Build LLVM and clang for WASM:
```bash
mkdir ~/wasm-compiler
cd ~/wasm-compiler
git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/llvm.git
cd llvm/tools
git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/clang.git
cd ..
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
make -j$( sysctl -in machdep.cpu.core_count )
make install
```
Add `WASM_LLVM_CONFIG` and `LLVM_DIR` to your `.bash_profile`:
```bash
echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_profile
echo "export LLVM_DIR=~/wasm-compiler/lib/cmake/llvm" >> ~/.bash_profile
echo "export LLVM_DIR=/usr/local/Cellar/llvm@4/4.0.1/lib/cmake/llvm/" >> ~/.bash_profile
source ~/.bash_profile
```
Your environment is set up. Now you can <a href="#runanode">build EOS and run a node</a>.
set(STANDARD_INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts ${CMAKE_SOURCE_DIR}/contracts/libc++/upstream/include ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/include ${Boost_INCLUDE_DIR})
# will be implictly used for any compilation unit if not overrided by SYSTEM_INCLUDE_FOLDERS parameter
# these directories go as -isystem <dir> to avoid warnings from code of third-party libraries
set(DEFAULT_SYSTEM_INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts/libc++/upstream/include ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/include ${Boost_INCLUDE_DIR})
set(STANDARD_INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts)
add_subdirectory(eosiolib)
add_subdirectory(musl)
......@@ -16,6 +20,9 @@ add_subdirectory(asserter)
add_subdirectory(infinite)
add_subdirectory(proxy)
add_subdirectory(test_api)
add_subdirectory(test_api_mem)
add_subdirectory(test_api_db)
add_subdirectory(test_api_multi_index)
#add_subdirectory(simpledb)
#add_subdirectory(storage)
#add_subdirectory(social)
......
......@@ -29,7 +29,22 @@
"fields": [
{"name":"value", "type":"string"}
]
},{
"name": "regproducer",
"base": "",
"fields": [
{"name":"producer", "type":"account_name"}
{"name":"producer_key", "type":"bytes"}
]
},{
"name": "stakevote",
"base": "",
"fields": [
{"name":"voter", "type":"account_name"}
{"name":"amount", "type":"asset"}
]
}
],
"actions": [{
"name": "transfer",
......@@ -40,6 +55,12 @@
},{
"name": "nonce",
"type": "nonce"
},{
"name": "regproducer",
"type": "regproducer"
},{
"name": "stakevote",
"type": "stakevote"
}
],
"tables": [{
......@@ -50,4 +71,4 @@
"key_types" : ["name"]
}
]
}
\ No newline at end of file
}
......@@ -11,6 +11,7 @@ extern "C" {
/// The apply method implements the dispatch of events to this contract
void apply( uint64_t code, uint64_t act ) {
print( eosio::name(code), "::", eosio::name(act) );
eosiosystem::contract<N(eosio)>::apply( code, act );
}
}
......@@ -14,13 +14,60 @@
#include <eosiolib/multi_index.hpp>
#include <eosiolib/privileged.h>
#include <algorithm>
#include <map>
namespace eosiosystem {
using eosio::indexed_by;
using eosio::const_mem_fun;
using eosio::bytes;
using std::map;
using std::pair;
using eosio::print;
template<account_name SystemAccount>
class contract {
public:
static const account_name system_account = SystemAccount;
typedef eosio::generic_currency< eosio::token<system_account,S(4,EOS)> > currency;
typedef typename currency::token_type system_token_type;
struct producer_votes {
account_name owner;
uint64_t padding = 0;
uint128_t total_votes;
uint64_t primary_key()const { return owner; }
uint128_t by_votes()const { return total_votes; }
EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) )
};
typedef eosio::multi_index< N(producervote), producer_votes,
indexed_by<N(prototalvote), const_mem_fun<producer_votes, uint128_t, &producer_votes::by_votes> >
> producer_votes_index_type;
struct account_votes {
account_name owner;
account_name proxy;
uint32_t last_update;
system_token_type staked;
std::vector<account_name> producers;
uint64_t primary_key()const { return owner; }
EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) )
};
typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type;
struct producer_config {
account_name owner;
eosio::bytes packed_key; /// a packed public key object
uint64_t primary_key()const { return owner; }
EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) )
};
typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type;
struct total_resources {
account_name owner;
......@@ -30,11 +77,10 @@ namespace eosiosystem {
uint64_t primary_key()const { return owner; }
EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) );
EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) )
};
/**
* Every user 'from' has a scope/table that uses every receipient 'to' as the primary key.
*/
......@@ -57,7 +103,7 @@ namespace eosiosystem {
EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)
(start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler)
(start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) );
(start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) )
};
......@@ -72,45 +118,55 @@ namespace eosiosystem {
};
ACTION( SystemAccount, regproducer ) {
account_name producer_to_register;
account_name producer;
bytes producer_key;
EOSLIB_SERIALIZE( regproducer, (producer_to_register) );
EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) )
};
ACTION( SystemAccount, regproxy ) {
account_name proxy_to_register;
EOSLIB_SERIALIZE( regproxy, (proxy_to_register) );
EOSLIB_SERIALIZE( regproxy, (proxy_to_register) )
};
ACTION( SystemAccount, delnetbw ) {
ACTION( SystemAccount, delegatebw ) {
account_name from;
account_name receiver;
typename currency::token_type stake_quantity;
typename currency::token_type stake_net_quantity;
typename currency::token_type stake_cpu_quantity;
EOSLIB_SERIALIZE( delnetbw, (from)(receiver)(stake_quantity) )
EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) )
};
ACTION( SystemAccount, undelnetbw ) {
ACTION( SystemAccount, undelegatebw ) {
account_name from;
account_name receiver;
typename currency::token_type stake_quantity;
typename currency::token_type unstake_net_quantity;
typename currency::token_type unstake_cpu_quantity;
EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) )
EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) )
};
ACTION( SystemAccount, nonce ) {
eosio::string value;
EOSLIB_SERIALIZE( nonce, (value) );
EOSLIB_SERIALIZE( nonce, (value) )
};
/// new id options:
// 1. hash + collision
// 2. incrementing count (key=> tablename
static void on( const delnetbw& del ) {
static void on( const delegatebw& del ) {
eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" );
eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" );
auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity;
eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" );
require_auth( del.from );
del_bandwidth_index_type del_index( SystemAccount, del.from );
......@@ -123,12 +179,14 @@ namespace eosiosystem {
del_index.emplace( del.from, [&]( auto& dbo ){
dbo.from = del.from;
dbo.to = del.receiver;
dbo.net_weight = del.stake_quantity;
dbo.net_weight = del.stake_net_quantity;
dbo.cpu_weight = del.stake_cpu_quantity;
});
}
else {
del_index.update( *itr, del.from, [&]( auto& dbo ){
dbo.net_weight = del.stake_quantity;
dbo.net_weight = del.stake_net_quantity;
dbo.cpu_weight = del.stake_cpu_quantity;
});
}
......@@ -136,25 +194,190 @@ namespace eosiosystem {
if( tot_itr == nullptr ) {
tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) {
tot.owner = del.receiver;
tot.total_net_weight += del.stake_quantity;
tot.total_net_weight += del.stake_net_quantity;
tot.total_cpu_weight += del.stake_cpu_quantity;
});
} else {
total_index.update( *tot_itr, 0, [&]( auto& tot ) {
tot.total_net_weight += del.stake_quantity;
tot.total_net_weight += del.stake_net_quantity;
tot.total_cpu_weight += del.stake_cpu_quantity;
});
}
set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 );
currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" );
} // delnetbw
currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" );
} // delegatebw
static void on( const undelegatebw& del ) {
eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" );
eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" );
auto total_stake = del.unstake_cpu_quantity + del.unstake_net_quantity;
eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" );
require_auth( del.from );
del_bandwidth_index_type del_index( SystemAccount, del.from );
total_resources_index_type total_index( SystemAccount, del.receiver );
//eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );
const auto& dbw = del_index.get(del.receiver);
eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" );
eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" );
del_index.update( dbw, del.from, [&]( auto& dbo ){
dbo.net_weight -= del.unstake_net_quantity;
dbo.cpu_weight -= del.unstake_cpu_quantity;
});
const auto& totals = total_index.get( del.receiver );
total_index.update( totals, 0, [&]( auto& tot ) {
tot.total_net_weight -= del.unstake_net_quantity;
tot.total_cpu_weight -= del.unstake_cpu_quantity;
});
set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 );
/// TODO: implement / enforce time delays on withdrawing
currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" );
} // undelegatebw
/**
* This method will create a producr_config and producer_votes object for 'producer'
*
* @pre producer is not already registered
* @pre producer to register is an account
* @pre authority of producer to register
*
*/
static void on( const regproducer& reg ) {
require_auth( reg.producer_to_register );
auto producer = reg.producer;
require_auth( producer );
producer_votes_index_type votes( SystemAccount, SystemAccount );
const auto* existing = votes.find( producer );
eosio_assert( !existing, "producer already registered" );
votes.emplace( producer, [&]( auto& pv ){
pv.owner = producer;
pv.total_votes = 0;
});
producer_config_index_type proconfig( SystemAccount, SystemAccount );
proconfig.emplace( producer, [&]( auto& pc ) {
pc.owner = producer;
pc.packed_key = reg.producer_key;
});
}
ACTION( SystemAccount, stakevote ) {
account_name voter;
system_token_type amount;
EOSLIB_SERIALIZE( stakevote, (voter)(amount) )
};
static void on( const stakevote& sv ) {
print( "on stake vote\n" );
eosio_assert( sv.amount.quantity > 0, "must stake some tokens" );
require_auth( sv.voter );
account_votes_index_type avotes( SystemAccount, SystemAccount );
const auto* acv = avotes.find( sv.voter );
if( !acv ) {
acv = &avotes.emplace( sv.voter, [&]( auto& av ) {
av.owner = sv.voter;
av.last_update = now();
av.proxy = 0;
});
}
uint128_t old_weight = acv->staked.quantity;
uint128_t new_weight = old_weight + sv.amount.quantity;
producer_votes_index_type votes( SystemAccount, SystemAccount );
for( auto p : acv->producers ) {
votes.update( votes.get( p ), 0, [&]( auto& v ) {
v.total_votes -= old_weight;
v.total_votes += new_weight;
});
}
avotes.update( *acv, 0, [&]( auto av ) {
av.last_update = now();
av.staked += sv.amount;
});
currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" );
}
ACTION( SystemAccount, voteproducer ) {
account_name voter;
account_name proxy;
std::vector<account_name> producers;
EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) )
};
/**
* @pre vp.producers must be sorted from lowest to highest
* @pre if proxy is set then no producers can be voted for
* @pre every listed producer or proxy must have been previously registered
* @pre vp.voter must authorize this action
* @pre voter must have previously staked some EOS for voting
*/
static void on( const voteproducer& vp ) {
eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" );
eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" );
if( vp.proxy != 0 ) eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" );
require_auth( vp.voter );
account_votes_index_type avotes( SystemAccount, SystemAccount );
const auto& existing = avotes.get( vp.voter );
std::map<account_name, pair<uint128_t, uint128_t> > producer_vote_changes;
uint128_t old_weight = existing.staked.quantity; /// old time
uint128_t new_weight = old_weight; /// TODO: update for current weight
for( const auto& p : existing.producers )
producer_vote_changes[p].first = old_weight;
for( const auto& p : vp.producers )
producer_vote_changes[p].second = new_weight;
producer_votes_index_type votes( SystemAccount, SystemAccount );
for( const auto& delta : producer_vote_changes ) {
if( delta.second.first != delta.second.second ) {
const auto& provote = votes.get( delta.first );
votes.update( provote, 0, [&]( auto& pv ){
pv.total_votes -= delta.second.first;
pv.total_votes += delta.second.second;
});
}
}
avotes.update( existing, 0, [&]( auto& av ) {
av.proxy = vp.proxy;
av.last_update = now();
av.producers = vp.producers;
});
}
static void on( const regproxy& reg ) {
require_auth( reg.proxy_to_register );
}
static void on( const nonce& ) {
......@@ -162,7 +385,11 @@ namespace eosiosystem {
static void apply( account_name code, action_name act ) {
if( !eosio::dispatch<contract, regproducer, regproxy, delnetbw, nonce>( code, act) ) {
if( !eosio::dispatch<contract,
regproducer, regproxy,
delegatebw, undelegatebw,
regproducer, voteproducer, stakevote,
nonce>( code, act) ) {
if ( !eosio::dispatch<currency, typename currency::transfer, typename currency::issue>( code, act ) ) {
eosio::print("Unexpected action: ", eosio::name(act), "\n");
eosio_assert( false, "received unexpected action");
......
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
namespace native {
/**
@defgroup eoscontract EOS Contract
@brief Documents the interface to the EOS currency contract
@ingroup contracts
@{
*/
/**
* @ingroup contracts
* @brief Defines the base class for all contracts
*/
struct contract {
/**
* @brief updates the code that will be executed for this contract
*
* <h3> Required Authority </h3>
*
* Requires authority of *this* contract.
*
* <h3> Required Scope </h3>
*
* Requires scope of *this* contract.
*
* @note the change in code does not take effect until the start of the next block
*/
void setcode( Bytes code,
Abi abi,
uint8_t vm = 0,
uint8_t vm_version = 0 ) final;
/**
* @brief updates the authority required for a named permission
*
* <h3> Required Authority </h3>
*
* Requires authority of *this* contract.
*
* <h3> Required Scope </h3>
*
* Requires scope of *this* contract.
*/
void setauth( Name permission, ///< the name for the permission being set
Name parent, ///< the parent permission to this permission
Authority auth ///< the set of keys/accounts and threshold );
) final;
/**
* @brief set the local named permission required for `this` account/contract to
* call `con::act(...)`
*
* <h3> Required Authority </h3>
*
* Requires authority of *this* contract.
*
* <h3> Required Scope </h3>
*
* Requires scope of *this* contract.
*
* @pre myperm must be defined by prior call to @ref setauth
*
* @param con - the name of the contract this permission applies
* @param act - the name of the action on @ref con this permission applies to
* @param myperm - the name of a permission set by @ref setauth on `this` contract
*/
void setperm( Name con, Name act, Name myperm );
};
/**
* @class eos
* @brief A *native* currency contract implemented with account named `eos`
* @ingroup contracts
*
* @details The EOS contract is a *native* currency contract implemented with account named `eos`. This contract enables
* users to transfer EOS tokens to each other. This contract is designed to work the @ref stakedcontract and
* @ref systemcontract when creating new accounts, claiming staked EOS.
*/
struct eos : public contract {
/**
@brief This action will transfer funds from one account to another.
@pre `from`'s balance must be greaterthan or equal to `amount` transferred.
@pre The amount transferred must be greater than 0
@pre `to` and `from` may not be the same account.
<h3> Required Authority </h3>
This action requires the authority of the `from` account.
<h3>Required Scope </h3>
This action requires access to `from` and `to` account scopes. It does not require
access to the `eos` scope which means that multiple transfers can execute in parallel
as long as they don't have any overlapping scopes.
<h3> Required Recipients </h3>
This action requires that the accounts `from` and `to` are listed in the required recipients. This ensures
other contracts are notified anytime EOS tokens are transferred.
*/
void transfer (
account_name from, ///< account from which EOS will be withdrawn
account_name to, ///< account to receive EOS, may not be same as `from`
uint64_t amount ///< must be greater than 0 and less or equal to `from`'s balance
);
}; /// class EOS
/// @}
}
......@@ -7,6 +7,7 @@
#pragma once
#include <eosiolib/account.h>
#include <eosiolib/print.hpp>
#include <eosiolib/asset.hpp>
namespace eosio { namespace account {
......@@ -68,13 +69,12 @@ struct PACKED(account_balance) {
/**
* @brief Retrieve a populated balance structure
* @details Retrieve a populated balance structure
* @param account_balance stream to write
* @ret true if account's balance is found
* @param acnt - account
* @return true if account's balance is found
*/
bool get(account_balance& b)
bool get(account_balance& acnt)
{
return account_balance_get(&b, sizeof(account_balance));
return account_balance_get(&acnt, sizeof(account_balance));
}
/// @} eosio
......
......@@ -112,8 +112,8 @@ extern "C" {
/**
* Send an inline action in the context of this action's parent transaction
* @param serialized_action
* @param size
* @param serialized_action - serialized action
* @param size - size of serialized action in bytes
*/
void send_inline(char *serialized_action, size_t size);
......
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosiolib/system.h>
extern "C" {
/**
* @defgroup compiler builtins API
* @brief Declares int128 helper builtins generated by the toolchain.
* @ingroup compilerbuiltinsapi
*
* @{
*/
/**
* Multiply two 128 bit integers split as two unsigned 64 bit integers and assign the value to the first parameter.
* @brief Multiply two 128 unsigned bit integers (which are represented as two 64 bit unsigned integers.
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* Example:
* @code
* __int128 res = 0;
* __int128 a = 100;
* __int128 b = 100;
* __multi3(res, a, (a >> 64), b, (b >> 64));
* printi128(res); // Output: 10000
* @endcode
*/
void __multi3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
void __divti3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
void __udivti3(unsigned __int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
void __modti3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
void __umodti3(unsigned __int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
void __lshlti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
void __lshrti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
void __ashlti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
void __ashrti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
void __break_point();
} // extern "C"
......@@ -30,7 +30,7 @@
}
```
`apply` is give the arguments `code` and `action` which uniquely identify every event in
`apply` is given the arguments `code` and `action` which uniquely identify every event in
the system. For example, `code` could be a *currency* contract and `action` could be *transfer*. This event (code,action)
may be passed to several contracts including the `sender` and `receiver`. It is up to your application to figure
out what to do in response to such an event.
......
......@@ -14,10 +14,76 @@ extern "C" {
*
* This method is optimized to a NO-OP when in fast evaluation mode
*/
void eosio_assert_sha256( char* data, uint32_t length, const checksum* hash );
void assert_sha256( char* data, uint32_t length, const checksum256* hash );
/**
* This method is implemented as:
*
* checksum calc_hash;
* sha1( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
*
* This method is optimized to a NO-OP when in fast evaluation mode
*/
void assert_sha1( char* data, uint32_t length, const checksum160* hash );
/**
* This method is implemented as:
*
* checksum calc_hash;
* sha512( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
*
* This method is optimized to a NO-OP when in fast evaluation mode
*/
void assert_sha512( char* data, uint32_t length, const checksum512* hash );
/**
* This method is implemented as:
*
* checksum calc_hash;
* ripemd160( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
*
* This method is optimized to a NO-OP when in fast evaluation mode
*/
void assert_ripemd160( char* data, uint32_t length, const checksum160* hash );
/**
* Calculates sha256( data,length) and stores result in memory pointed to by hash
* `hash` should be checksum<256>
*/
void sha256( char* data, uint32_t length, checksum256* hash );
/**
* Calculates sha1( data,length) and stores result in memory pointed to by hash
* `hash` should be checksum<160>
*/
void sha1( char* data, uint32_t length, checksum160* hash );
/**
* Calculates sha512( data,length) and stores result in memory pointed to by hash
* `hash` should be checksum<512>
*/
void sha256( char* data, uint32_t length, checksum* hash );
void sha512( char* data, uint32_t length, checksum512* hash );
/**
* Calculates ripemd160( data,length) and stores result in memory pointed to by hash
* `hash` should be checksum<160>
*/
void ripemd160( char* data, uint32_t length, checksum160* hash );
/**
* Calculates the public key used for a given signature and hash used to create a message and places it in `pub`
* returns the number of bytes read into pub
* `digest` should be checksum<256>
*/
int recover_key( checksum256* digest, const char* sig, size_t siglen, char* pub, size_t publen );
/**
* Tests a given public key with the generated key from digest and the signature
* `digest` should be checksum<256>
*/
void assert_recover_key( checksum256* digest, const char* sig, size_t siglen, const char* pub, size_t publen );
}
......@@ -18,7 +18,7 @@ template<typename T>
class datastream {
public:
datastream( T start, size_t s )
:_start(start),_pos(start),_end(start+s){};
:_start(start),_pos(start),_end(start+s){}
/**
* Skips a specified number of bytes from this stream
......@@ -99,7 +99,7 @@ class datastream {
* @brief Gets the position within the current stream
* @return p the position within the current stream
*/
inline size_t tellp()const { return _pos - _start; }
inline size_t tellp()const { return size_t(_pos - _start); }
/**
* Returns the number of remaining bytes that can be read/skipped
......@@ -119,7 +119,7 @@ class datastream {
template<>
class datastream<size_t> {
public:
datastream( size_t init_size = 0):_size(init_size){};
datastream( size_t init_size = 0):_size(init_size){}
inline bool skip( size_t s ) { _size += s; return true; }
inline bool write( const char* ,size_t s ) { _size += s; return true; }
inline bool put(char ) { ++_size; return true; }
......
......@@ -304,8 +304,6 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param scope - the account scope that will be read, must exist in the transaction scopes list
* @param code - identifies the code that controls write-access to the data
* @param table - the ID/name of the table within the scope/code context to query
* @param key - location of the record key
* @param keylen - length of the record key
* @param value - location to copy the front record value
* @param valuelen - maximum length of the record value to read
* @return the number of bytes read or -1 if key was not found
......@@ -316,8 +314,6 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param scope - the account scope that will be read, must exist in the transaction scopes list
* @param code - identifies the code that controls write-access to the data
* @param table - the ID/name of the table within the scope/code context to query
* @param key - location of the record key
* @param keylen - length of the record key
* @param value - location to copy the back record value
* @param valuelen - maximum length of the record value to read
* @return the number of bytes read or -1 if key was not found
......
此差异已折叠。
......@@ -47,7 +47,7 @@ namespace eosio {
return nullptr;
}
const uint32_t new_heap_size = remaining > _new_heap_size ? _new_heap_size : remaining;
const uint32_t new_heap_size = uint32_t(remaining) > _new_heap_size ? _new_heap_size : uint32_t(remaining);
char* new_memory_start = static_cast<char*>(sbrk(new_heap_size));
// if we can expand the current memory, keep working with it
if (current_memory->expand_memory(new_memory_start, new_heap_size))
......@@ -75,7 +75,6 @@ namespace eosio {
adjust_to_mem_block(size);
// first pass of loop never has to initialize the slot in _available_heap
uint32_t needs_init = 0;
char* buffer = nullptr;
memory* current = nullptr;
// need to make sure
......@@ -129,7 +128,6 @@ namespace eosio {
return nullptr;
}
const uint32_t REMOVE = size;
adjust_to_mem_block(size);
char* realloc_ptr = nullptr;
......@@ -283,12 +281,11 @@ namespace eosio {
return nullptr;
}
const int32_t diff = size - *orig_ptr_size;
if (diff < 0)
if( *orig_ptr_size > size )
{
// use a buffer_ptr to allocate the memory to free
char* const new_ptr = ptr + size + _size_marker;
buffer_ptr excess_to_free(new_ptr, -diff, _heap + _heap_size);
buffer_ptr excess_to_free(new_ptr, *orig_ptr_size - size, _heap + _heap_size);
excess_to_free.mark_free();
return ptr;
......@@ -297,11 +294,11 @@ namespace eosio {
else if (orig_buffer_end == &_heap[_offset])
{
orig_buffer.size(size);
_offset += diff;
_offset += size - *orig_ptr_size;
return ptr;
}
if (-diff == 0)
if (size == *orig_ptr_size )
return ptr;
if (!orig_buffer.merge_contiguous_if_available(size))
......@@ -418,7 +415,7 @@ namespace eosio {
bool merge_contiguous(uint32_t needed_size, bool all_or_nothing)
{
// do not bother if there isn't contiguious space to allocate
if (all_or_nothing && _heap_end - _ptr < needed_size)
if( all_or_nothing && uint32_t(_heap_end - _ptr) < needed_size )
return false;
uint32_t possible_size = _size;
......@@ -472,7 +469,7 @@ namespace eosio {
uint32_t _heaps_actual_size;
uint32_t _active_heap;
uint32_t _active_free_heap;
static const uint32_t _alloc_memory_mask = 1 << 31;
static const uint32_t _alloc_memory_mask = uint32_t(1) << 31;
};
memory_manager memory_heap;
......
#pragma once
#include <eosiolib/types.h>
#include <eosiolib/print.hpp>
namespace eosio
{
......@@ -148,8 +149,15 @@ ope * fixed_point128<3> b(a);
if(!Q) return 0;
return val << (32-Q);
}
void print() const {
uint128_t ip(int_part());
uint128_t fp(frac_part());
printi128(&ip);
prints(".");
printi128(&fp);
}
// Various assignment operators
template <uint8_t qr> fixed_point128 &operator=(const fixed_point32<qr> &r);
template <uint8_t qr> fixed_point128 &operator=(const fixed_point64<qr> &r);
......@@ -225,6 +233,12 @@ ope * fixed_point128<3> b(a);
return val << (32-Q);
}
void print() const {
printi(int_part());
prints(".");
printi128(frac_part());
}
// Various assignment operators
template <uint8_t QR> fixed_point64 &operator=(const fixed_point32<QR> &r);
template <uint8_t QR> fixed_point64 &operator=(const fixed_point64<QR> &r);
......@@ -295,6 +309,12 @@ ope * fixed_point128<3> b(a);
return val << (32-Q);
}
void print() const {
printi(int_part());
prints(".");
printi128(frac_part());
}
// Various assignment operators
template <uint8_t QR> fixed_point32 &operator=(const fixed_point32<QR> &r);
template <uint8_t QR> fixed_point32 &operator=(const fixed_point64<QR> &r);
......@@ -440,6 +460,7 @@ ope * fixed_point128<3> b(a);
// std::cout << "Performing division on " << val << ", with " << q << " precision / " << r.val << ", with " << qr << " precision. Result precision " << ((q>qr) ? q:qr) << std::endl;
// Convert val to 128 bit by additionally shifting 64 bit and take the result to 128bit
// Q(X+64-Y) = Q(X+64) / Q(Y)
eosio_assert( !(r.int_part() == 0 && r.frac_part() == 0), "divide by zero" );
return fixed_point128<Q+64-QR>((int128_t(val)<<64)/r.val);
}
......@@ -536,6 +557,7 @@ ope * fixed_point128<3> b(a);
fixed_point64<Q+32-QR> fixed_point32<Q>::operator/(const fixed_point32<QR> &r) const {
// Convert val into 64 bit and perform the division
// Q(X+32-Y) = Q(X+32) / Q(Y)
eosio_assert( !(r.int_part() == 0 && r.frac_part() == 0), "divide by zero" );
return fixed_point64<Q+32-QR>((int64_t(val)<<32)/r.val);
}
......@@ -552,6 +574,8 @@ ope * fixed_point128<3> b(a);
template <uint8_t Q>
fixed_point64<Q> fixed_divide(uint32_t lhs, uint32_t rhs)
{
eosio_assert( rhs != 0, "divide by zero" );
fixed_point64<Q> result = fixed_point32<0>(lhs) / fixed_point32<0>(rhs);
return result;
}
......@@ -569,6 +593,8 @@ ope * fixed_point128<3> b(a);
template <uint8_t Q>
fixed_point128<Q> fixed_divide(uint64_t lhs, uint64_t rhs)
{
eosio_assert( rhs != 0, "divide by zero" );
fixed_point128<Q> result = fixed_point64<0>(lhs) / fixed_point64<0>(rhs);
return fixed_point128<Q>(result);
}
......
......@@ -130,7 +130,7 @@ namespace eosio {
static void inline_transfer( account_name from, account_name to, token_type quantity,
string memo = string() )
{
action act( permission_level(code,N(active)), transfer_memo( from, to, asset(quantity), move(memo) ));
action act( permission_level(from,N(active)), transfer_memo( from, to, asset(quantity), move(memo) ));
act.send();
}
......
......@@ -157,7 +157,7 @@ extern "C" {
* Convert double (interpreted as 64 bit unsigned integer) to 64 bit unsigned integer.
* This function will first reinterpret_cast the input to double (50 decimal digit precision) then convert it to double, then reinterpret_cast it to 64 bit unsigned integer.
* @brief Convert double to 64 bit unsigned integer
* @param self Value in double interpreted as 64 bit unsigned integer
* @param a - value in double interpreted as 64 bit unsigned integer
* @return Result of conversion in 64 bit unsigned integer
*
* Example:
......@@ -173,7 +173,7 @@ extern "C" {
* Convert 64 bit unsigned integer to double (interpreted as 64 bit unsigned integer).
* This function will convert the input to double (50 decimal digit precision) then reinterpret_cast it to 64 bit unsigned integer.
* @brief Convert 64 bit unsigned integer to double (interpreted as 64 bit unsigned integer)
* @param self Value to be converted
* @param a - value to be converted
* @return Result of conversion in double (interpreted as 64 bit unsigned integer)
*
* Example:
......
......@@ -36,7 +36,7 @@ int db_idx_store( uint64_t scope, uint64_t table, uint64_t payer, uint64_t id, c
void db_idx_update( int iterator, uint64_t payer, const TYPE& secondary ) {\
db_##IDX##_update( iterator, payer, &secondary );\
}\
int db_idx_find_primary( uint64_t code, uint64_t scope, uint64_t table, TYPE& secondary, uint64_t primary ) {\
int db_idx_find_primary( uint64_t code, uint64_t scope, uint64_t table, uint64_t primary, TYPE& secondary ) {\
return db_##IDX##_find_primary( code, scope, table, &secondary, primary );\
}\
int db_idx_find_secondary( uint64_t code, uint64_t scope, uint64_t table, const TYPE& secondary, uint64_t& primary ) {\
......@@ -58,73 +58,94 @@ MAKE_SECONDARY_ITERATOR(idx256, uint256)
template<uint64_t TableName, typename T, typename... Indices>
class multi_index;
template<uint64_t IndexName, typename Extractor>
struct indexed_by {
enum constants { index_name = IndexName };
typedef Extractor secondary_extractor_type;
typedef decltype( Extractor()(nullptr) ) secondary_type;
};
template<int IndexNumber, uint64_t IndexName, typename T, typename Extractor, uint64_t TableName>
template<uint64_t TableName, uint64_t IndexName, typename T, typename Extractor, int N = 0>
struct index_by {
//typedef typename std::decay<decltype( (Extractor())( *((const T*)(nullptr)) ) )>::type value_type;
typedef Extractor extractor_secondary_type;
typedef decltype( Extractor()(nullptr) ) secondary_type;
typedef Extractor extractor_secondary_type;
typedef typename std::decay<decltype( Extractor()(nullptr) )>::type secondary_type;
index_by(){}
static const int index_number = IndexNumber;
static const uint64_t index_name = IndexName;
static const uint64_t table_name = TableName;
enum constants {
table_name = TableName,
index_name = IndexName,
index_number = N,
// index_table_name = (TableName & 0xFFFFFFFFFFFFFFF0ULL) | (N & 0x000000000000000FULL) // Assuming no more than 16 secondary indices are allowed
};
constexpr static int number() { return N; }
constexpr static uint64_t name() {
return IndexName;
// return index_table_name;
}
private:
template<uint64_t, typename, typename... >
friend class multi_index;
Extractor extract_secondary_key;
/*
constexpr static bool validate_table_name(uint64_t n) {
// Limit table names to 12 characters so that the last character (4 bits) can be used to distinguish between the secondary indices.
return (n & 0x000000000000000FULL) == 0;
}
static_assert( validate_table_name(TableName), "currently only table names of maximum length 12 are supported by multi_index");
*/
int store( uint64_t scope, uint64_t payer, const T& obj ) {
return db_idx_store( scope, TableName, payer, obj.primary_key(), extract_secondary_key(&obj) );
static auto extract_secondary_key(const T& obj) { return extractor_secondary_type()(obj); }
static int store( uint64_t scope, uint64_t payer, const T& obj ) {
return db_idx_store( scope, name(), payer, obj.primary_key(), extract_secondary_key(obj) );
}
void update( int iterator, uint64_t payer, const secondary_type& secondary ) {
static void update( int iterator, uint64_t payer, const secondary_type& secondary ) {
db_idx_update( iterator, payer, secondary );
}
int find_primary( uint64_t code, uint64_t scope, uint64_t primary, secondary_type& secondary )const {
return db_idx_find_primary( code, scope, TableName, secondary, primary );
static int find_primary( uint64_t code, uint64_t scope, uint64_t primary, secondary_type& secondary ) {
return db_idx_find_primary( code, scope, name(), primary, secondary );
}
void remove( int itr ) {
static void remove( int itr ) {
secondary_iterator<secondary_type>::db_idx_remove( itr );
}
int find_secondary( uint64_t code, uint64_t scope, secondary_type& secondary, uint64_t& primary )const {
return db_idx_find_secondary( code, scope, TableName, secondary, primary );
static int find_secondary( uint64_t code, uint64_t scope, secondary_type& secondary, uint64_t& primary ) {
return db_idx_find_secondary( code, scope, name(), secondary, primary );
}
int lower_bound( uint64_t code, uint64_t scope, secondary_type& secondary, uint64_t& primary )const {
return db_idx_lowerbound( code, scope, TableName, secondary, primary );
static int lower_bound( uint64_t code, uint64_t scope, secondary_type& secondary, uint64_t& primary ) {
return db_idx_lowerbound( code, scope, name(), secondary, primary );
}
int upper_bound( uint64_t code, uint64_t scope, secondary_type& secondary, uint64_t& primary )const {
return db_idx_upperbound( code, scope, TableName, secondary, primary );
static int upper_bound( uint64_t code, uint64_t scope, secondary_type& secondary, uint64_t& primary ) {
return db_idx_upperbound( code, scope, name(), secondary, primary );
}
};
/*
template<int IndexNumber, uint64_t IndexName, typename T, typename Extractor>
auto make_index_by( Extractor&& l ) {
return index_by<IndexNumber, IndexName, T, Extractor>{ std::forward<Extractor>(l) };
}
*/
namespace hana = boost::hana;
template<uint64_t TableName, typename T, typename... Indices>
class multi_index
{
private:
/*
template<bool...> struct bool_pack;
template<bool... bs>
using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
static_assert(all_true<(TableName == Indices::table_name)...>::value, "index must use same table name as the multi_index it is contained within");
*/
static_assert( sizeof...(Indices) <= 6, "currently only a maximum of 6 secondary indices are supported" ); // See transform_indices implementation below for the reason.
struct item : public T
{
......@@ -136,7 +157,7 @@ class multi_index
const multi_index& __idx;
int __primary_itr;
int __iters[sizeof...(Indices)];
int __iters[sizeof...(Indices)+(sizeof...(Indices)==0)];
};
uint64_t _code;
......@@ -144,8 +165,29 @@ class multi_index
uint64_t _next_primary_key;
boost::hana::tuple<Indices...> _indices;
template<uint64_t I>
struct intc { enum e{ value = I }; operator uint64_t()const{ return I; } };
static constexpr auto transform_indices( ) {
typedef decltype( hana::zip_shortest(
hana::make_tuple( intc<0>(), intc<1>(), intc<2>(), intc<3>(), intc<4>(), intc<5>() ), // QUESTION: We only allow up to 6 secondary indices?
hana::tuple<Indices...>() ) ) indices_input_type;
return hana::transform( indices_input_type(), [&]( auto&& idx ){
typedef typename std::decay<decltype(hana::at_c<0>(idx))>::type num_type;
typedef typename std::decay<decltype(hana::at_c<1>(idx))>::type idx_type;
return index_by<TableName,
idx_type::index_name,
T,
typename idx_type::secondary_extractor_type,
num_type::e::value>();
});
}
typedef decltype( multi_index::transform_indices() ) indices_type;
indices_type _indices;
struct by_primary_key;
struct by_primary_itr;
......@@ -157,9 +199,6 @@ class multi_index
>
> _items_index;
// mutable std::map<uint64_t, item*> _items; /// by_primary_key
// mutable std::map<int, item*> _items_by_itr;
const item& load_object_by_primary_iterator( int itr )const {
const auto& by_pitr = _items_index.template get<by_primary_itr>();
auto cacheitr = by_pitr.find( itr );
......@@ -167,10 +206,11 @@ class multi_index
return *cacheitr;
auto size = db_get_i64( itr, nullptr, 0 );
eosio_assert( size >= 0, "error reading iterator" );
char tmp[size];
db_get_i64( itr, tmp, size );
db_get_i64( itr, tmp, uint32_t(size) );
datastream<const char*> ds(tmp,size);
datastream<const char*> ds(tmp,uint32_t(size));
auto result = _items_index.emplace( *this, [&]( auto& i ) {
T& val = static_cast<T&>(i);
......@@ -178,7 +218,7 @@ class multi_index
i.__primary_itr = itr;
boost::hana::for_each( _indices, [&]( auto& idx ) {
i.__iters[idx.index_number] = -1;
i.__iters[ idx.number() ] = -1;
});
});
......@@ -204,14 +244,17 @@ class multi_index
}
}
~multi_index() {
}
uint64_t get_code()const { return _code; }
uint64_t get_scope()const { return _scope; }
template<typename MultiIndexType, typename IndexType>
template<typename MultiIndexType, typename IndexType, uint64_t Number>
struct index {
private:
typedef typename MultiIndexType::item item_type;
typedef typename IndexType::secondary_type secondary_key_type;
public:
static constexpr uint64_t name() { return IndexType::name(); }
struct const_iterator {
public:
......@@ -232,9 +275,17 @@ class multi_index
const_iterator& operator++() {
if( !_item ) return *this;
if( _item->__iters[Number] == -1 ) {
/// TODO: lookup iter for this item in this index
secondary_key_type temp_secondary_key;
auto idxitr = db_idx_find_primary(_idx.get_code(),
_idx.get_scope(),
_idx.name(),
_item->primary_key(), temp_secondary_key);
}
uint64_t next_pk = 0;
auto next_itr = secondary_iterator<secondary_key_type>::db_idx_next( _item->__iters[IndexType::index_number], &next_pk );
auto next_itr = secondary_iterator<secondary_key_type>::db_idx_next( _item->__iters[Number], &next_pk );
if( next_itr < 0 ) {
_item = nullptr;
return *this;
......@@ -242,7 +293,7 @@ class multi_index
const T& obj = *_idx._multidx.find( next_pk );
auto& mi = const_cast<item_type&>( static_cast<const item_type&>(obj) );
mi.__iters[IndexType::index_number] = next_itr;
mi.__iters[Number] = next_itr;
_item = &mi;
return *this;
......@@ -253,11 +304,11 @@ class multi_index
int prev_itr = -1;
if( !_item ) {
auto ei = secondary_iterator<secondary_key_type>::db_idx_end(_idx._multidx._code, _idx._multidx._scope, TableName);
auto ei = secondary_iterator<secondary_key_type>::db_idx_end(_idx.get_code(), _idx.get_scope(), _idx.name());
prev_itr = secondary_iterator<secondary_key_type>::db_idx_previous( ei , &prev_pk );
}
else
prev_itr = secondary_iterator<secondary_key_type>::db_idx_previous( _item->__iters[IndexType::index_number], &prev_pk );
prev_itr = secondary_iterator<secondary_key_type>::db_idx_previous( _item->__iters[Number], &prev_pk );
if( prev_itr < 0 ) {
_item = nullptr;
......@@ -266,7 +317,7 @@ class multi_index
const T& obj = *_idx._multidx.find( prev_pk );
auto& mi = const_cast<item_type&>( static_cast<const item_type&>(obj) );
mi.__iters[IndexType::index_number] = prev_itr;
mi.__iters[Number] = prev_itr;
_item = &mi;
return *this;
......@@ -276,7 +327,7 @@ class multi_index
const T* operator->()const { return static_cast<const T*>(_item); }
private:
friend class index;
friend struct index;
const_iterator( const index& idx, const typename MultiIndexType::item* i = nullptr )
:_idx(idx), _item(i){}
......@@ -294,12 +345,12 @@ class multi_index
const_iterator lower_bound( const typename IndexType::secondary_type& secondary )const {
uint64_t primary = 0;
typename IndexType::secondary_type secondary_copy(secondary);
auto itr = _idx.lower_bound( _multidx._code, _multidx._scope, secondary_copy, primary );
auto itr = IndexType::lower_bound( get_code(), get_scope(), secondary_copy, primary );
if( itr < 0 ) return end();
const T& obj = *_multidx.find( primary );
auto& mi = const_cast<item_type&>( static_cast<const item_type&>(obj) );
mi.__iters[IndexType::index_number] = itr;
mi.__iters[Number] = itr;
return const_iterator( *this, &mi );
}
......@@ -309,24 +360,25 @@ class multi_index
const_iterator upper_bound( const typename IndexType::secondary_type& secondary )const {
uint64_t primary = 0;
typename IndexType::secondary_type secondary_copy(secondary);
auto itr = _idx.upper_bound( _multidx._code, _multidx._scope, secondary_copy, primary );
auto itr = IndexType::upper_bound( get_code(), get_scope(), secondary_copy, primary );
if( itr < 0 ) return end();
const T& obj = *_multidx.find( primary );
auto& mi = const_cast<item_type&>( static_cast<const item_type&>(obj) );
mi.__iters[IndexType::index_number] = itr;
mi.__iters[Number] = itr;
return const_iterator( *this, &mi );
}
uint64_t get_code()const { return _multidx.get_code(); }
uint64_t get_scope()const { return _multidx.get_scope(); }
private:
friend class const_iterator;
friend class multi_index;
index( const MultiIndexType& midx, const IndexType& idx )
:_multidx(midx),_idx(idx){}
index( const MultiIndexType& midx ) //, const IndexType& idx )
:_multidx(midx){}
const MultiIndexType& _multidx;
const IndexType& _idx;
const MultiIndexType _multidx;
};
......@@ -354,11 +406,10 @@ class multi_index
uint64_t next_pk;
auto next_itr = db_next_i64( _item->__primary_itr, &next_pk );
if( next_itr < 0 ) {
if( next_itr < 0 )
_item = nullptr;
return *this;
}
_item = &_multidx.load_object_by_primary_iterator( next_itr );
else
_item = &_multidx.load_object_by_primary_iterator( next_itr );
return *this;
}
const_iterator& operator--() {
......@@ -374,11 +425,10 @@ class multi_index
else
prev_itr = db_previous_i64( _item->__primary_itr, &prev_pk );
if( prev_itr < 0 ) {
if( prev_itr < 0 )
_item = nullptr;
return *this;
}
_item = &_multidx.load_object_by_primary_iterator( prev_itr );
else
_item = &_multidx.load_object_by_primary_iterator( prev_itr );
return *this;
}
......@@ -419,9 +469,11 @@ class multi_index
template<uint64_t IndexName>
auto get_index()const {
const auto& idx = boost::hana::find_if( _indices, []( auto x ){
return std::integral_constant<bool,(decltype(x)::index_name == IndexName)>(); } ).value();
return index<multi_index, typename std::decay<decltype(idx)>::type>( *this, idx );
auto idx = boost::hana::find_if( _indices, []( auto&& in ) {
return std::integral_constant<bool, std::decay<decltype(in)>::type::index_name == IndexName>();
}).value();
return index<multi_index, decltype(idx), idx.number()>( *this );
}
template<typename Lambda>
......@@ -442,7 +494,7 @@ class multi_index
_next_primary_key = std::min(pk, static_cast<uint64_t>(-2)) + 1;
boost::hana::for_each( _indices, [&]( auto& idx ) {
i.__iters[idx.index_number] = idx.store( _scope, payer, obj );
i.__iters[idx.number()] = idx.store( _scope, payer, obj );
});
});
......@@ -457,7 +509,7 @@ class multi_index
// eosio_assert( &objitem.__idx == this, "invalid object" );
auto secondary_keys = boost::hana::transform( _indices, [&]( auto& idx ) {
auto secondary_keys = boost::hana::transform( _indices, [&]( auto&& idx ) {
return idx.extract_secondary_key( obj );
});
......@@ -476,18 +528,25 @@ class multi_index
_next_primary_key = std::min(pk, static_cast<uint64_t>(-2)) + 1;
boost::hana::for_each( _indices, [&]( auto& idx ) {
typedef typename std::decay<decltype(idx)>::type index_type;
auto secondary = idx.extract_secondary_key( obj );
if( boost::hana::at_c<std::decay<decltype(idx)>::type::index_number>(secondary_keys) != secondary ) {
auto indexitr = mutableitem.__iters[idx.index_number];
if( hana::at_c<index_type::index_number>(secondary_keys) != secondary ) {
auto indexitr = mutableitem.__iters[idx.number()];
if( indexitr < 0 )
indexitr = mutableitem.__iters[idx.index_number] = idx.find_primary( _code, _scope, pk, secondary );
indexitr = mutableitem.__iters[idx.number()] = idx.find_primary( _code, _scope, pk, secondary );
idx.update( indexitr, payer, secondary );
}
});
}
const T& get( uint64_t primary )const {
auto result = find( primary );
eosio_assert( result != nullptr, "unable to find key" );
return *result;
}
const T* find( uint64_t primary )const {
auto cacheitr = _items_index.find(primary);
if( cacheitr != _items_index.end() )
......@@ -508,7 +567,7 @@ class multi_index
db_remove_i64( objitem.__primary_itr );
boost::hana::for_each( _indices, [&]( auto& idx ) {
auto i = objitem.__iters[idx.index_number];
auto i = objitem.__iters[idx.number()];
if( i < 0 ) {
typename std::decay<decltype(idx)>::type::secondary_type second;
i = idx.find_primary( _code, _scope, objitem.primary_key(), second );
......
extern "C" {
/**
*
* @return an ID that serves as an iterator to the object stored, -1 for error
*/
int db_store_i64( uint64_t scope, uint64_t table, uint64_t payer, uint64_t id, char* buffer, size_t buffer_size );
int db_update_i64( int iterator, char* buffer, size_t buffer_size );
/**
* max_buffer_size should start out with the space reserved for buffer, but is set to the actual size of buffer
*
* if max_buffer_size is greater than actual buffer size, then buffer will be filled with contents, otherwise not
*
* @return an ID that serves as an iterator to the object stored, -1 for error/not found
*/
int db_find_i64( uint64_t code, uint64_t scope, uint64_t table, uint64_t id, char* buffer, size_t* max_buffer_size );
int db_lower_bound_i64( uint64_t code, uint64_t scope, uint64_t table, uint64_t id, char* buffer, size_t* max_buffer_size );
int db_upper_bound_i64( uint64_t code, uint64_t scope, uint64_t table, uint64_t id, char* buffer, size_t* max_buffer_size );
/** return an iterator to the next item after @param iterator and optionally fetch data if buffer is not null */
int db_next( int iterator, uint64_t* id, char* buffer, size_t* max_buffer_size );
/** return an iterator to the prev item after @param iterator and optionally fetch data if buffer is not null */
int db_prev( int iterator, uint64_t* id, char* buffer, size_t* max_buffer_size );
/**
* @return the number of elements in the table stored at code/scope/table
*/
int db_count_i64( uint64_t code, uint64_t scope, uint64_t table );
void db_remove_i64( int iterator );
int db_find_primary_index64( uint64_t scope, uint64_t table, uint64_t primary, uint64_t* secondary );
int db_find_secondary_index64( uint64_t scope, uint64_t table, uint64_t* primary, uint64_t secondary );
int db_upper_bound_primary_index64( uint64_t scope, uint64_t table, uint64_t primary, uint64_t* secondary );
int db_upper_bound_secondary_index64( uint64_t scope, uint64_t table, uint64_t* primary, uint64_t secondary );
int db_lower_bound_primary_index64( uint64_t scope, uint64_t table, uint64_t primary, uint64_t* secondary );
int db_lower_bound_secondary_index64( uint64_t scope, uint64_t table, uint64_t* primary, uint64_t secondary );
int db_update_index64( int iterator, uint64_t payer, uint64_t id, uint64_t indexvalue );
int db_remove_index64( int iterator );
int db_next_index64( int iterator, uint64_t* value );
int db_prev_index64( int iterator, uint64_t* value );
int db_find_primary_index128( uint64_t scope, uint64_t table, uint64_t primary, uint128_t* secondary );
int db_find_secondary_index128( uint64_t scope, uint64_t table, uint64_t* primary, const uint128_t* secondary );
int db_upper_bound_primary_index128( uint64_t scope, uint64_t table, uint64_t primary, uint128_t* secondary );
int db_upper_bound_secondary_index128( uint64_t scope, uint64_t table, uint64_t* primary, const uint128_t* secondary );
int db_lower_bound_primary_index128( uint64_t scope, uint64_t table, uint64_t primary, uint128_t* secondary );
int db_lower_bound_secondary_index128( uint64_t scope, uint64_t table, uint64_t* primary, const uint128_t* secondary );
int db_update_index128( int iterator, uint64_t payer, uint64_t id, const uint128_t* secondary );
int db_remove_index128( int iterator );
int db_next_index128( int iterator, uint128_t* value );
int db_prev_index128( int iterator, uint128_t* value );
} /// extern "C"
namespace eosio {
namespace detail {
template<typename T>
struct id_for{};
}
struct limit_order {
uint64_t id;
uint128_t price;
uint64_t expiration;
account_name owner;
uint128_t by_owner_id()const {
uint128_t result(owner);
result << 64;
result |= id;
return result;
}
uint128_t by_price()const { return price; }
uint64_t by_expiration()const { return expiration; }
EOSLIB_SERIALIZE( (id)(price)(expiration)(owner) )
};
template<uint64_t Number, uint64_t IndexName, typename Extractor>
class index_by {
typedef std::decay<decltype( ex( *((const T*)(nullptr)) ) )>::type value_type
static const uint64_t index_name = IndexName;
static const uint64_t number = Number;
Extractor ex;
};
template<typename T, typename IndexTuple>
class multi_index {
auto indicies = make_tuple( make_index(N(byorderid), []( const T& obj ){ return obj.id; }),
make_index(N(byexpiration), []( const T& obj) { return obj.by_expiration(); } )
make_index(N(byprice), []( const T& obj) { return obj.by_price(); } ) );
mutable map<uint64_t, item*> _items;
public:
template<uint64_t IndexName, typename Key>
const T* find( const Key& k )const {
}
template<typename Existing>
auto get_keys( const T& obj ) {
return get_keys<1>( std::make_tuple(
}
template<int I, typename Existing, std::enable_if< I == std::tuple_size(IndexTuple) - 1> = 0 >
auto get_keys( Existing&& e, const T& obj ) {
return std::tuple_cat( std::forward<Existing>(e), std::get<I>( indicies ).extract( obj ) );
}
template<int I, typename Existing, std::enable_if< (I < std::tuple_size(IndexTuple) - 1) > = 0 >
auto get_keys( Existing&& e, const T& obj ) {
return get_keys<I+1>( std::tuple_cat( std::forward<Existing>(e), std::get<I>( indicies ).extract( obj ) ), obj );
}
template<typename Lambda>
const T& create( Lambda&& constructor, uint64_t payer ) {
auto i = new item( *this );
constructor( static_cast<T&>(*i) );
const T& obj = static_cast<const T&>(*i);
char tmp[ pack_size( obj ) ];
datastream<char*> ds( tmp, sizeof(tmp) );
pack( ds, obj );
auto pk = obj.primary_key();
i->__itrs[0] = db_store_i64( _code, _scope, _tables[0], payer, pk, tmp, sizeof(tmp) );
for_each( indicies, [&]( auto& idx ) {
i->__itrs[idx.number] = idx.store( _code, _scope, idx.index_name, payer, pk, idx.extract( obj ) );
});
items[pk] = i;
return obj;
}
template<typename Lambda>
void update( const T& obj, uint64_t payer, Lambda&& updater ) {
T& mobj = const_cast<T&>(obj);
item& i = static_cast<item&>(mobj);
auto pk = mobj.primary_key();
eosio_assert( &i.__mutli_idx == this );
auto old_idx = std::make_tuple(
obj.primary_key(), obj.expiration(), obj.by_owner_id(), obj.by_price() );
updater(mobj);
char tmp[ pack_size( mobj ) ];
datastream<char*> ds( tmp, sizeof(tmp) );
pack( ds, mobj );
db_update_i64( i.__itrs[0], payer, tmp, sizeof(tmp) );
auto new_idx = std::make_tuple(
obj.primary_key(), obj.expiration(), obj.by_owner_id(), obj.by_price() );
if( std::get<1>(old_idx) != std::get<1>(new_idx) ) {
if( i.__itrs[1] == -2 ) i.__itrs[1] = db_idx64_find_primary( pk );
db_idx64_update( i.__itrs[1], payer, std::get<1>(new_idx) );
}
if( std::get<2>(old_idx) != std::get<2>(new_idx) ) {
if( i.__itrs[2] == -2 ) i.__itrs[2] = db_idx64_find_primary( pk );
db_idx64_update( i.__itrs[2], payer, std::get<2>(new_idx) );
}
if( std::get<3>(old_idx) != std::get<3>(new_idx) ) {
if( i.__itrs[3] == -2 ) i.__itrs[3] = db_idx64_find_primary( pk );
db_idx64_update( i.__itrs[3], payer, std::get<3>(new_idx) );
}
}
private:
struct item : public T
{
item( multi_index& o ):__mutli_idx(o) {
}
multi_index& __multi_idx;
int __itrs[3];
};
};
/*
multi_index< N(limitorders), limit_order,
index< N(ownerid), &limit_order::by_owner_id >,
index< N(byprice), &limit_order::by_price >,
index< N(byexpire), &limit_order::by_expiration>
> orderbook;
*/
/*
template<uint64_t Code, uint64_t TableName, typename ObjectType>
class multi_index {
public:
struct cache_object : public ObjectType {
int primary_itr;
};
const cache_object* find( uint64_t primary ) {
auto itr = _cache.find( primary );
if( itr != cache.end() )
return itr->second;
db_find_i64( Code, _scope, TableName, primary );
}
private:
std::map<uint64_t, cache_object*> _cache;
};
auto order = orderbook.begin();
auto end = orderbook.end();
while( order != end ) {
auto cur = order;
++order;
orderbook.remove( cur );
}
const limit_order& order = *orderbook.begin();
/// Options:
// 1. maintain a wasm-side cache of all dereferenced objects
// a. keeps pointers valid
// b. minimizes temporary copies
// c. eliminates redundant deserialization losses
// d. will utilize more heap memory than necessary, potentially hitting sbrk
//
// 2. keep API light and return a copy
template<typename ObjectType, typename SecondaryKeyType>
class index
{
public:
index( uint64_t code, uint64_t scope, uint64_t table );
struct iterator {
iterator( index& idx, int itr )
:_idx(idx), _itr(itr){
if( itr >= 0 )
db_index<SecondaryKeyType>::get( itr, _primary, _secondary );
}
uint64_t primary()const { return _primary; }
const SecondaryKeyType& secondary()const { return _secondary; }
private:
uint64_t _primary;
SecondaryKeyType _secondary;
index& _idx;
int _itr;
};
iterator lower_bound( const SecondaryKeyType& lb ) {
return iterator( db_index<SecondaryKeyType>::secondary_lower_bound( _code, _scope, _table, lb ) );
}
private:
uint64_t _code;
uint64_t _scope;
uint64_t _table;
};
template<typename T, typename Indices>
class multi_index {
public:
struct iterator {
private:
int primary_itr;
};
multi_index( code_name code, scope_name scope, table_name table )
:_code(code),_scope(scope),_table(table){}
void insert( const T& obj, account_name payer ) {
uint64_t id = id_for<T>::get(obj);
auto buf = pack(obj);
store_i64( _scope, _table, payer, id, buf.data(), buf.size() );
Indices::insert( _code, _scope, _table, payer, obj );
}
template<typename Constructor>
void emplace( Constructor&& c ) {
T tmp;
id_for<T>::get(tmp) = allocate_id();
c(tmp);
insert( tmp );
}
template<typename Lambda>
void modify( const T& obj, account_name payer, Lambda&& update ) {
update(tmp);
uint64_t id = id_for<T>::get(value);
auto buf = pack(tmp);
store_i64( _code, _scope, _table, payer, id, buf.data(), buf.size() );
Indices::update( _code, _scope, _table, payer, obj );
}
private:
};
} // namespace eosio
......@@ -51,7 +51,7 @@ extern "C" {
/**
* Prints value as a 64 bit unsigned integer
* @brief Prints value as a 64 bit unsigned integer
* @param Value of 64 bit unsigned integer to be printed
* @param value of 64 bit unsigned integer to be printed
*
* Example:
* @code
......@@ -74,16 +74,16 @@ extern "C" {
void printi128( const uint128_t* value );
/**
* Prints a 256 bit unsigned integer as a hexidecimal string
* @brief Prints a 256 bit unsigned integer as a hexidecimal string
* @param Value of 256 bit integer to be printed
* Prints value as a hexidecimal string
* @brief Prints value as a hexidecimal string
* @param value 256 bit integer to be printed
*/
void printi256( const uint256* value );
/**
* Prints value as double
* @brief Prints value as double
* @param Value of double (interpreted as 64 bit unsigned integer) to be printed
* @param value of double (interpreted as 64 bit unsigned integer) to be printed
*
* Example:
* @code
......@@ -96,7 +96,7 @@ extern "C" {
/**
* Prints a 64 bit names as base32 encoded string
* @brief Prints a 64 bit names as base32 encoded string
* @param Value of 64 bit names to be printed
* @param name - 64 bit name to be printed
*
* Example:
* @code
......@@ -108,6 +108,7 @@ extern "C" {
/**
*/
void printhex( void* data, uint32_t datalen );
/// @}
#ifdef __cplusplus
}
......
......@@ -15,7 +15,7 @@ namespace eosio {
/**
* Prints string
* @brief Prints string
* @param cstr - a null terminated string
* @param ptr - a null terminated string
*/
inline void print( const char* ptr ) {
prints(ptr);
......@@ -24,7 +24,7 @@ namespace eosio {
/**
* Prints 64 bit unsigned integer as a 64 bit unsigned integer
* @brief Prints integer 64 bit unsigned integer
* @param Value to be printed
* @param num to be printed
*/
inline void print( uint64_t num ) {
printi(num);
......@@ -33,7 +33,7 @@ namespace eosio {
/**
* Prints 32 bit unsigned integer as a 64 bit unsigned integer
* @brief Prints integer 32 bit unsigned integer
* @param Value to be printed
* @param num to be printed
*/
inline void print( uint32_t num ) {
printi(num);
......@@ -42,16 +42,16 @@ namespace eosio {
/**
* Prints integer as a 64 bit unsigned integer
* @brief Prints integer
* @param Value to be printed
* @param num to be printed
*/
inline void print( int num ) {
printi(num);
printi(uint64_t(num));
}
/**
* Prints unsigned integer as a 64 bit unsigned integer
* @brief Prints unsigned integer
* @param Value to be printed
* @param num to be printed
*/
inline void print( unsigned int num ) {
printi(num);
......@@ -60,7 +60,7 @@ namespace eosio {
/**
* Prints uint128 struct as 128 bit unsigned integer
* @brief Prints uint128 struct
* @param Value to be printed
* @param num to be printed
*/
inline void print( uint128 num ) {
printi128((uint128_t*)&num);
......@@ -69,16 +69,16 @@ namespace eosio {
/**
* Prints 128 bit unsigned integer
* @brief Prints 128 bit unsigned integer
* @param Value to be printed
* @param num to be printed
*/
inline void print( uint128_t num ) {
printi128(&num);
}
/**
* Prints a 256 bit unsigned integer as a hexidecimal string
* @brief Prints a 256 bit unsigned integer as a hexidecimal string
* @param Value of 256 bit integer to be printed
* Prints 256 bit unsigned integer as a hexidecimal string
* @brief Prints 256 bit unsigned integer as a hexidecimal string
* @param num to be printed
*/
inline void print( const uint256& num ) {
printi256(&num);
......@@ -87,7 +87,7 @@ namespace eosio {
/**
* Prints a 64 bit names as base32 encoded string
* @brief Prints a 64 bit names as base32 encoded string
* @param Value of 64 bit names to be printed
* @param name 64 bit name to be printed
*/
inline void print( name name ) {
printn(name.value);
......@@ -103,6 +103,24 @@ namespace eosio {
}
inline void print_f( const char* s ) {
prints(s);
}
template <typename Arg, typename... Args>
inline void print_f( const char* s, Arg val, Args... rest ) {
while ( *s != '\0' ) {
if ( *s == '%' ) {
print( val );
print_f( s+1, rest... );
return;
}
prints_l( s, 1 );
s++;
}
}
/**
* @defgroup consoleCppapi Console C++ API
* @ingroup consoleapi
......
......@@ -16,9 +16,11 @@ extern "C" {
* @{
*/
void set_resource_limits( account_name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight, int64_t ignored);
void set_resource_limits( account_name account, uint64_t ram_bytes, uint64_t net_weight, uint64_t cpu_weight, int64_t ignored);
void set_active_producers( char *producer_data, size_t producer_data_size );
bool is_privileged( account_name account );
///@ } privilegedcapi
}
......@@ -92,8 +92,6 @@ namespace eosio {
* @brief Compares two double variables c1 and c2
*
* @details Compares two double variables c1 and c2
* @param c1
* @param c2
* @return if c1 == c2, return true, otherwise false
*/
bool operator==(const real &c1, const real &c2) {
......@@ -105,8 +103,6 @@ namespace eosio {
* @brief Compares two double variables c1 and c2
*
* @details Compares two double variables c1 and c2
* @param c1
* @param c2
* @return if c1 > c2, return true, otherwise false
*/
bool operator>(const real &c1, const real &c2) {
......@@ -118,8 +114,6 @@ namespace eosio {
* @brief Compares two double variables c1 and c2
*
* @details Compares two double variables c1 and c2
* @param c1
* @param c2
* @return if c1 < c2, return true, otherwise false
*/
bool operator<(const real &c1, const real &c2) {
......
......@@ -38,7 +38,7 @@ namespace eosio {
if ( read < 0 ) {
return def;
}
return unpack<T>( temp + sizeof(SingletonName), read );
return unpack<T>( temp + sizeof(SingletonName), size_t(read) );
}
static T get_or_create( scope_name scope = Code, const T& def = T() ) {
......
......@@ -23,7 +23,7 @@ namespace eosio {
auto read = load_i64( DefaultScope, scope , TableName, temp, sizeof(temp) );
eosio_assert( read > 0, "key does not exist" );
datastream<const char*> ds(temp, read);
datastream<const char*> ds(temp, uint32_t(read) );
T result;
ds >> result;
return result;
......@@ -39,7 +39,7 @@ namespace eosio {
return def;
}
datastream<const char*> ds(temp, read);
datastream<const char*> ds(temp, uint32_t(read) );
T result;
ds >> result;
return result;
......@@ -54,7 +54,7 @@ namespace eosio {
return def;
}
datastream<const char*> ds(temp, read);
datastream<const char*> ds(temp, uint32_t(read) );
T result;
ds >> result;
return result;
......
......@@ -49,7 +49,7 @@ namespace eosio {
* @brief Constructor for token given quantity of tokens available
* @param v - quantity of tokens available
*/
explicit token( NumberType v ):quantity(v){};
explicit token( NumberType v ):quantity(v){}
/**
* Quantity of tokens available
......
......@@ -72,26 +72,22 @@ extern "C" {
/**
* get the size of the currently executing transaction
* @return
*/
size_t transaction_size();
/**
* get the block number used for TAPOS on the currently executing transaction
*
* @return
*/
int tapos_block_num();
/**
* get the block prefix used for TAPOS on the currently executing transaction
* @return
*/
int tapos_block_prefix();
/**
* get the expiration of the currently executing transaction
* @return
*/
time expiration();
......
......@@ -24,8 +24,8 @@ namespace eosio {
class transaction {
public:
transaction(time expiration = now() + 60, region_id region = 0)
:expiration(expiration),region(region)
transaction(time exp = now() + 60, region_id r = 0)
:expiration(exp),region(r)
{}
void send(uint32_t sender_id, time delay_until = 0) const {
......@@ -36,11 +36,14 @@ namespace eosio {
time expiration;
region_id region;
uint16_t ref_block_num;
uint32_t ref_block_id;
uint32_t ref_block_prefix;
uint16_t packed_bandwidth_words = 0; /// number of 8 byte words this transaction can compress into
uint16_t context_free_cpu_bandwidth = 0; /// number of CPU usage units to bill transaction for
vector<action> context_free_actions;
vector<action> actions;
EOSLIB_SERIALIZE( transaction, (expiration)(region)(ref_block_num)(ref_block_id)(actions) );
EOSLIB_SERIALIZE( transaction, (expiration)(region)(ref_block_num)(ref_block_prefix)(packed_bandwidth_words)(context_free_cpu_bandwidth)(context_free_actions)(actions) )
};
class deferred_transaction : public transaction {
......
......@@ -6,6 +6,10 @@
#include <stdint.h>
#include <wchar.h>
/*
struct checksum_base {
};
*/
#ifdef __cplusplus
extern "C" {
......@@ -34,15 +38,23 @@ typedef int64_t share_type;
#define PACKED(X) __attribute((packed)) X
struct public_key {
uint8_t data[33];
char data[34];
};
struct signature {
uint8_t data[65];
uint8_t data[66];
};
struct checksum256 {
uint8_t hash[32];
};
struct checksum160 {
uint8_t hash[20];
};
struct checksum {
uint64_t hash[4];
struct checksum512 {
uint8_t hash[64];
};
struct fixed_string16 {
......
......@@ -13,7 +13,7 @@ namespace eosio {
* @details Converts a base32 symbol into its binary representation, used by string_to_name()
* @ingroup types
*/
static constexpr char char_to_symbol( char c ) {
static constexpr char char_to_symbol( char c ) {
if( c >= 'a' && c <= 'z' )
return (c - 'a') + 6;
if( c >= '1' && c <= '5' )
......@@ -39,7 +39,7 @@ namespace eosio {
for( uint32_t i = 0; i <= 12; ++i ) {
uint64_t c = 0;
if( i < len && i <= 12 ) c = char_to_symbol( str[i] );
if( i < len && i <= 12 ) c = uint64_t(char_to_symbol( str[i] ));
if( i < 12 ) {
c &= 0x1f;
......
......@@ -23,7 +23,7 @@ struct unsigned_int {
template<typename T>
operator T()const { return static_cast<T>(value); }
unsigned_int& operator=( int32_t v ) { value = v; return *this; }
unsigned_int& operator=( uint32_t v ) { value = v; return *this; }
uint32_t value;
......@@ -102,7 +102,7 @@ struct signed_int {
template<typename DataStream>
friend DataStream& operator << ( DataStream& ds, const signed_int& v ){
uint32_t val = (v.value<<1) ^ (v.value>>31);
uint32_t val = uint32_t((v.value<<1) ^ (v.value>>31));
do {
uint8_t b = uint8_t(val) & 0x7f;
val >>= 7;
......
......@@ -141,7 +141,7 @@ namespace identity {
key.uint64s[3] = 0;
return key;
}
uint256 get_key() const { return key(property, trusted, certifier); };
uint256 get_key() const { return key(property, trusted, certifier); }
EOSLIB_SERIALIZE( certrow , (property)(trusted)(certifier)(confidence)(type)(data) )
};
......@@ -164,7 +164,7 @@ namespace identity {
//typedef table_i64i64i64<code, N(certs), code, certrow> certs_table;
typedef eosio::multi_index<N(certs), certrow,
eosio::index_by<0, N(bytuple), certrow, eosio::const_mem_fun<certrow, uint256, &certrow::get_key>, N(certs) >
eosio::indexed_by< N(bytuple), eosio::const_mem_fun<certrow, uint256, &certrow::get_key> >
> certs_table;
typedef eosio::multi_index<N(ident), identrow> idents_table;
typedef singleton<code, N(account), code, identity_name> accounts_table;
......
......@@ -9,6 +9,7 @@ FOREACH(FN ${SRC_FILENAMES})
ENDFOREACH(FN)
add_wast_library(TARGET libc++
NOWARNINGS
SOURCE_FILES "${SRC_FILES}"
INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
......
......@@ -2,7 +2,7 @@
file(GLOB ABI_FILES "*.abi")
set(ABI_FILES "multi_index_test.abi")
add_wast_executable(TARGET multi_index_test
INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" /usr/local/include
INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
LIBRARIES libc++ libc eosiolib
DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
)
......
......@@ -6,11 +6,12 @@ using namespace eosio;
namespace multi_index_test {
struct limit_order {
uint64_t id;
uint128_t price;
uint64_t expiration;
account_name owner;
struct limit_order {
uint64_t id;
uint64_t padding = 0;
uint128_t price;
uint64_t expiration;
account_name owner;
auto primary_key()const { return id; }
uint64_t get_expiration()const { return expiration; }
......@@ -51,8 +52,8 @@ namespace multi_index_test {
{
print("Testing uint128_t secondary index.\n");
eosio::multi_index<N(orders), limit_order,
index_by<0, N(byexp), limit_order, const_mem_fun<limit_order, uint64_t, &limit_order::get_expiration>, N(orders)>,
index_by<1, N(byprice), limit_order, const_mem_fun<limit_order, uint128_t, &limit_order::get_price>, N(orders)>
indexed_by< N(byexp), const_mem_fun<limit_order, uint64_t, &limit_order::get_expiration> >,
indexed_by< N(byprice), const_mem_fun<limit_order, uint128_t, &limit_order::get_price> >
> orders( N(multitest), N(multitest) );
const auto& order1 = orders.emplace( payer, [&]( auto& o ) {
......@@ -99,7 +100,7 @@ namespace multi_index_test {
{
print("Testing uint256 secondary index.\n");
eosio::multi_index<N(test1), test_u256,
index_by<0, N(byval), test_u256, const_mem_fun<test_u256, uint256, &test_u256::get_val>, N(test1)>
indexed_by< N(byval), const_mem_fun<test_u256, uint256, &test_u256::get_val> >
> testtable( N(multitest), N(exchange) ); // Code must be same as the receiver? Scope doesn't have to be.
const auto& entry1 = testtable.emplace( payer, [&]( auto& o ) {
......
......@@ -16,6 +16,7 @@ file(GLOB THREAD_SOURCES "upstream/src/thread/*.c") #only for __lock __unlock
set(INTERNAL_SOURCES upstream/src/internal/intscan.c upstream/src/internal/shgetc.c upstream/src/internal/libc.c)
add_wast_library(TARGET libc
NOWARNINGS
SOURCE_FILES ${CRYPT_SOURCES} ${CTYPE_SOURCES} ${ENV_SOURCES} ${ERRNO_SOURCES} ${EXIT_SOURCES} ${INTERNAL_SOURCES} ${LOCALE_SOURCES} ${MBYTE_SOURCES}
${MISC_SOURCES} ${SEARCH_SOURCES} ${STDIO_SOURCES} ${STDLIB_SOURCES} ${STRING_SOURCES} ${TIME_SOURCES} ${THREAD_SOURCES}
INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/include
......
......@@ -2,8 +2,6 @@
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <stltest/stltest.hpp> /// defines transfer struct (abi)
// include entire libc
#include <alloca.h>
#include <assert.h>
......@@ -195,7 +193,7 @@ namespace stltest {
prints("f() called\n");
}
static void on(const message& msg) {
static void on( const message& ) {
/* manual initialization of global variable
new(&std::__start_std_streams)std::ios_base::Init;
*/
......@@ -246,7 +244,7 @@ namespace stltest {
std::map<int, long> m;
m.emplace(0, 1);
auto mit = m.lower_bound(2);
m.lower_bound(2);
std::set<long> st;
st.insert(0);
......@@ -259,7 +257,7 @@ namespace stltest {
//hs.insert(0);
sort(dq.begin(), dq.end());
auto lit = find_if(l.begin(), l.end(), [](uint32_t f) { return f < 10; });
find_if(l.begin(), l.end(), [](uint32_t f) { return f < 10; });
prints("STL test done.\n");
//std::cout << "STL test done." << std::endl;
}
......
#pragma once
\ No newline at end of file
......@@ -4,6 +4,7 @@
*/
#include <eosiolib/action.hpp>
#include <eosiolib/chain.h>
#include <eosiolib/types.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/system.h>
......@@ -18,46 +19,41 @@ namespace testsystem {
};
struct set_account_limits : dispatchable<N(setalimits)> {
account_name account;
int64_t ram_bytes;
int64_t net_weight;
int64_t cpu_weight;
account_name account;
uint64_t ram_bytes = 0;
uint64_t net_weight = 0;
uint64_t cpu_weight = 0;
static void process(const set_account_limits& act) {
set_resource_limits(act.account, act.ram_bytes, act.net_weight, act.cpu_weight, 0);
}
EOSLIB_SERIALIZE( set_account_limits, (account)(ram_bytes)(net_weight)(cpu_weight) );
EOSLIB_SERIALIZE( set_account_limits, (account)(ram_bytes)(net_weight)(cpu_weight) )
};
struct set_global_limits : dispatchable<N(setglimits)> {
int64_t cpu_usec_per_period;
static void process(const set_global_limits& act) {
static void process(const set_global_limits& ) {
// TODO: support this
}
EOSLIB_SERIALIZE( set_global_limits, (cpu_usec_per_period) );
EOSLIB_SERIALIZE( set_global_limits, (cpu_usec_per_period) )
};
struct producer_key {
account_name account;
std::string public_key;
EOSLIB_SERIALIZE( producer_key, (account)(public_key) );
EOSLIB_SERIALIZE( producer_key, (account) ) //(public_key) )
};
struct set_producers : dispatchable<N(setprods)> {
uint32_t version;
vector<producer_key> producers;
static void process(const set_producers&) {
char buffer[action_size()];
read_action( buffer, sizeof(buffer) );
set_active_producers(buffer, sizeof(buffer));
}
EOSLIB_SERIALIZE( set_producers, (version)(producers) );
};
struct require_auth : dispatchable<N(reqauth)> {
......@@ -93,7 +89,6 @@ namespace testsystem {
using dispatcher = dispatcher_impl<set_account_limits, set_global_limits, set_producers, require_auth>;
};
extern "C" {
/// The apply method implements the dispatch of events to this contract
......
/**
* @file test_account.cpp
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/account.hpp>
#include <eosiolib/eos.hpp>
#include <eosiolib/system.h>
#include "test_api.hpp"
/// must match #define in eos/types/asset.hpp
#define EOS_SYMBOL (int64_t(4) | (uint64_t('E') << 8) | (uint64_t('O') << 16) | (uint64_t('S') << 24))
unsigned int test_account::test_balance_acc1()
{
eosio::print("test_balance_acc1\n");
eosio::account::account_balance b;
b.account = N(acc1);
WASM_ASSERT(eosio::account::get(b), "account_balance_get should have found \"acc1\"");
WASM_ASSERT(b.account == N(acc1), "account_balance_get should not change the account");
WASM_ASSERT(b.eos_balance.amount == 24, "account_balance_get should have set a balance of 24");
WASM_ASSERT(b.eos_balance.symbol == EOS_SYMBOL, "account_balance_get should have a set a balance symbol of EOS");
WASM_ASSERT(b.staked_balance.amount == 23, "account_balance_get should have set a staked balance of 23");
WASM_ASSERT(b.staked_balance.symbol == EOS_SYMBOL, "account_balance_get should have a set a staked balance symbol of EOS");
WASM_ASSERT(b.unstaking_balance.amount == 14, "account_balance_get should have set a unstaking balance of 14");
WASM_ASSERT(b.unstaking_balance.symbol == EOS_SYMBOL, "account_balance_get should have a set a unstaking balance symbol of EOS");
WASM_ASSERT(b.last_unstaking_time == 55, "account_balance_get should have set a last unstaking time of 55");
return WASM_TEST_PASS;
}
/**
* @file
* @copyright defined in eos/LICENSE.txt
* @file action_test.cpp
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/action.hpp>
#include "test_api.hpp"
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/compiler_builtins.h>
#include "test_api.hpp"
void test_action::read_action_normal() {
char buffer[100];
......@@ -28,37 +31,37 @@ void test_action::read_action_normal() {
eosio_assert(total == sizeof(dummy_action), "read_action(sizeof(dummy_action))" );
dummy_action *dummy13 = reinterpret_cast<dummy_action *>(buffer);
eosio_assert(dummy13->a == DUMMY_MESSAGE_DEFAULT_A, "dummy13->a == DUMMY_MESSAGE_DEFAULT_A");
eosio_assert(dummy13->b == DUMMY_MESSAGE_DEFAULT_B, "dummy13->b == DUMMY_MESSAGE_DEFAULT_B");
eosio_assert(dummy13->c == DUMMY_MESSAGE_DEFAULT_C, "dummy13->c == DUMMY_MESSAGE_DEFAULT_C");
eosio_assert(dummy13->a == DUMMY_ACTION_DEFAULT_A, "dummy13->a == DUMMY_ACTION_DEFAULT_A");
eosio_assert(dummy13->b == DUMMY_ACTION_DEFAULT_B, "dummy13->b == DUMMY_ACTION_DEFAULT_B");
eosio_assert(dummy13->c == DUMMY_ACTION_DEFAULT_C, "dummy13->c == DUMMY_ACTION_DEFAULT_C");
}
void test_action::read_action_to_0() {
uint32_t total = read_action((void *)0, 0x7FFFFFFF);
uint32_t total = read_action((void *)0, action_size());
}
void test_action::read_action_to_64k() {
uint32_t total = read_action( (void *)((1<<16)-1), 0x7FFFFFFF);
uint32_t total = read_action( (void *)((1<<16)-2), action_size());
}
void test_action::require_notice() {
if( current_receiver() == N(testapi) ) {
eosio::require_recipient( N(acc1) );
eosio::require_recipient( N(acc2) );
eosio::require_recipient( N(acc1), N(acc2) );
eosio_assert(false, "Should've failed");
} else if ( current_receiver() == N(acc1) || current_receiver() == N(acc2) ) {
return;
}
eosio_assert(false, "Should've failed");
}
//unsigned int test_action::require_notice() {
// if( current_receiver() == N(testapi) ) {
// eosio::require_recipient( N(acc1) );
// eosio::require_recipient( N(acc2) );
// eosio::require_recipient( N(acc1), N(acc2) );
// return WASM_TEST_FAIL;
// } else if ( current_receiver() == N(acc1) || current_receiver() == N(acc2) ) {
// return WASM_TEST_PASS;
// }
// return WASM_TEST_FAIL;
//}
//
//unsigned int test_action::require_auth() {
// eosio::require_auth( N(acc3) );
// eosio::require_auth( N(acc4) );
// return WASM_TEST_PASS;
//}
void test_action::require_auth() {
prints("require_auth");
eosio::require_auth( N(acc3) );
eosio::require_auth( N(acc4) );
}
void test_action::assert_false() {
eosio_assert(false, "test_action::assert_false");
......@@ -68,11 +71,33 @@ void test_action::assert_true() {
eosio_assert(true, "test_action::assert_true");
}
//unsigned int test_action::now() {
// uint32_t tmp = 0;
// uint32_t total = read_action(&tmp, sizeof(uint32_t));
// WASM_ASSERT( total == sizeof(uint32_t), "total == sizeof(uint32_t)");
// WASM_ASSERT( tmp == ::now(), "tmp == now()" );
// return WASM_TEST_PASS;
//}
//
void test_action::test_abort() {
abort();
eosio_assert( false, "should've aborted" );
}
void test_action::test_publication_time() {
uint32_t pub_time = 0;
read_action(&pub_time, sizeof(uint32_t));
eosio_assert( pub_time == publication_time(), "pub_time == publication_time()" );
}
void test_action::test_current_receiver() {
account_name cur_rec;
read_action(&cur_rec, sizeof(account_name));
eosio_assert( current_receiver() == cur_rec, "the current receiver does not match" );
}
void test_action::test_current_sender() {
account_name cur_send;
read_action(&cur_send, sizeof(account_name));
eosio_assert( current_sender() == cur_send, "the current sender does not match" );
}
void test_action::now() {
uint32_t tmp = 0;
uint32_t total = read_action(&tmp, sizeof(uint32_t));
eosio_assert( total == sizeof(uint32_t), "total == sizeof(uint32_t)");
eosio_assert( tmp == ::now(), "tmp == now()" );
}
......@@ -5,20 +5,17 @@
#include <eosiolib/eosio.hpp>
#include "test_api.hpp"
//#include "test_account.cpp"
//#include "test_chain.cpp"
//#include "test_crypto.cpp"
//#include "test_db.cpp"
//#include "test_math.cpp"
#include "test_action.cpp"
#include "test_print.cpp"
//#include "test_string.cpp"
//#include "test_fixedpoint.cpp"
//#include "test_real.cpp"
//#include "test_transaction.cpp"
//#include "test_types.cpp"
#include "test_db.cpp"
#include "test_multi_index.cpp"
#include "test_types.cpp"
#include "test_fixedpoint.cpp"
#include "test_math.cpp"
#include "test_compiler_builtins.cpp"
#include "test_real.cpp"
#include "test_crypto.cpp"
#include "test_chain.cpp"
#include "test_transaction.cpp"
#include "test_checktime.cpp"
extern "C" {
......@@ -29,149 +26,117 @@ extern "C" {
void apply( unsigned long long code, unsigned long long action ) {
//eosio::print("==> CONTRACT: ", code, " ", action, "\n");
//test_types
// WASM_TEST_HANDLER(test_types, types_size);
// WASM_TEST_HANDLER(test_types, char_to_symbol);
// WASM_TEST_HANDLER(test_types, string_to_name);
// WASM_TEST_HANDLER(test_types, name_class);
//
// //test_action
WASM_TEST_HANDLER(test_types, types_size);
WASM_TEST_HANDLER(test_types, char_to_symbol);
WASM_TEST_HANDLER(test_types, string_to_name);
WASM_TEST_HANDLER(test_types, name_class);
//test_compiler_builtins
WASM_TEST_HANDLER(test_compiler_builtins, test_multi3);
WASM_TEST_HANDLER(test_compiler_builtins, test_divti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_divti3_by_0);
WASM_TEST_HANDLER(test_compiler_builtins, test_udivti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_udivti3_by_0);
WASM_TEST_HANDLER(test_compiler_builtins, test_modti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_modti3_by_0);
WASM_TEST_HANDLER(test_compiler_builtins, test_umodti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_umodti3_by_0);
WASM_TEST_HANDLER(test_compiler_builtins, test_lshlti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_lshrti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_ashlti3);
WASM_TEST_HANDLER(test_compiler_builtins, test_ashrti3);
//test_action
WASM_TEST_HANDLER(test_action, read_action_normal);
WASM_TEST_HANDLER(test_action, read_action_to_0);
WASM_TEST_HANDLER(test_action, read_action_to_64k);
// WASM_TEST_HANDLER(test_action, require_notice);
// WASM_TEST_HANDLER(test_action, require_auth);
WASM_TEST_HANDLER(test_action, require_notice);
WASM_TEST_HANDLER(test_action, require_auth);
WASM_TEST_HANDLER(test_action, assert_false);
WASM_TEST_HANDLER(test_action, assert_true);
// WASM_TEST_HANDLER(test_action, now);
WASM_TEST_HANDLER(test_action, now);
WASM_TEST_HANDLER(test_action, test_abort);
WASM_TEST_HANDLER(test_action, test_current_receiver);
WASM_TEST_HANDLER(test_action, test_current_sender);
WASM_TEST_HANDLER(test_action, test_publication_time);
//test_print
WASM_TEST_HANDLER(test_print, test_prints);
WASM_TEST_HANDLER(test_print, test_prints_l);
WASM_TEST_HANDLER(test_print, test_printi);
WASM_TEST_HANDLER(test_print, test_printi128);
WASM_TEST_HANDLER(test_print, test_printn);
// //test_math
// WASM_TEST_HANDLER(test_math, test_multeq_i128);
// WASM_TEST_HANDLER(test_math, test_diveq_i128);
// WASM_TEST_HANDLER(test_math, test_diveq_i128_by_0);
// WASM_TEST_HANDLER(test_math, test_double_api);
// WASM_TEST_HANDLER(test_math, test_double_api_div_0);
//
//
// //test db
// WASM_TEST_HANDLER(test_db, key_i64_general);
// WASM_TEST_HANDLER(test_db, key_i64_remove_all);
// WASM_TEST_HANDLER(test_db, key_i64_small_load);
// WASM_TEST_HANDLER(test_db, key_i64_small_store);
// WASM_TEST_HANDLER(test_db, key_i64_store_scope);
// WASM_TEST_HANDLER(test_db, key_i64_remove_scope);
// WASM_TEST_HANDLER(test_db, key_i64_not_found);
// WASM_TEST_HANDLER(test_db, key_i64_front_back);
// WASM_TEST_HANDLER(test_db, key_i64i64i64_general);
// WASM_TEST_HANDLER(test_db, key_i128i128_general);
// WASM_TEST_HANDLER(test_db, key_str_general);
// WASM_TEST_HANDLER(test_db, key_str_table);
// WASM_TEST_HANDLER(test_db, key_str_setup_limit);
// WASM_TEST_HANDLER(test_db, key_str_min_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_str_under_limit);
// WASM_TEST_HANDLER(test_db, key_str_available_space_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_str_another_under_limit);
// WASM_TEST_HANDLER(test_db, key_i64_setup_limit);
// WASM_TEST_HANDLER(test_db, key_i64_min_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_i64_under_limit);
// WASM_TEST_HANDLER(test_db, key_i64_available_space_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_i64_another_under_limit);
// WASM_TEST_HANDLER(test_db, key_i128i128_setup_limit);
// WASM_TEST_HANDLER(test_db, key_i128i128_min_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_i128i128_under_limit);
// WASM_TEST_HANDLER(test_db, key_i128i128_available_space_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_i128i128_another_under_limit);
// WASM_TEST_HANDLER(test_db, key_i64i64i64_setup_limit);
// WASM_TEST_HANDLER(test_db, key_i64i64i64_min_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_i64i64i64_under_limit);
// WASM_TEST_HANDLER(test_db, key_i64i64i64_available_space_exceed_limit);
// WASM_TEST_HANDLER(test_db, key_i64i64i64_another_under_limit);
WASM_TEST_HANDLER(test_db, primary_i64_general);
WASM_TEST_HANDLER(test_db, primary_i64_lowerbound);
WASM_TEST_HANDLER(test_db, primary_i64_upperbound);
WASM_TEST_HANDLER(test_db, idx64_general);
WASM_TEST_HANDLER(test_db, idx64_lowerbound);
WASM_TEST_HANDLER(test_db, idx64_upperbound);
//test multi_index
WASM_TEST_HANDLER(test_multi_index, idx64_general);
WASM_TEST_HANDLER(test_multi_index, idx64_store_only);
WASM_TEST_HANDLER(test_multi_index, idx64_check_without_storing);
WASM_TEST_HANDLER(test_multi_index, idx128_autoincrement_test);
WASM_TEST_HANDLER(test_multi_index, idx128_autoincrement_test_part1);
WASM_TEST_HANDLER(test_multi_index, idx128_autoincrement_test_part2);
// //test crypto
// WASM_TEST_HANDLER(test_crypto, test_sha256);
// WASM_TEST_HANDLER(test_crypto, sha256_no_data);
// WASM_TEST_HANDLER(test_crypto, asert_sha256_false);
// WASM_TEST_HANDLER(test_crypto, asert_sha256_true);
// WASM_TEST_HANDLER(test_crypto, asert_no_data);
//
// //test transaction
// WASM_TEST_HANDLER(test_transaction, send_message);
// WASM_TEST_HANDLER(test_transaction, send_message_empty);
// WASM_TEST_HANDLER(test_transaction, send_message_max);
// WASM_TEST_HANDLER(test_transaction, send_message_large);
// WASM_TEST_HANDLER(test_transaction, send_message_recurse);
// WASM_TEST_HANDLER(test_transaction, send_message_inline_fail);
// WASM_TEST_HANDLER(test_transaction, send_transaction);
// WASM_TEST_HANDLER(test_transaction, send_transaction_empty);
// WASM_TEST_HANDLER(test_transaction, send_transaction_max);
// WASM_TEST_HANDLER(test_transaction, send_transaction_large);
//
// //test chain
// WASM_TEST_HANDLER(test_chain, test_activeprods);
//
// // test string
// WASM_TEST_HANDLER(test_string, construct_with_size);
// WASM_TEST_HANDLER(test_string, construct_with_data);
// WASM_TEST_HANDLER(test_string, construct_with_data_copied);
// WASM_TEST_HANDLER(test_string, construct_with_data_partially);
// WASM_TEST_HANDLER(test_string, copy_constructor);
// WASM_TEST_HANDLER(test_string, assignment_operator);
// WASM_TEST_HANDLER(test_string, index_operator);
// WASM_TEST_HANDLER(test_string, index_out_of_bound);
// WASM_TEST_HANDLER(test_string, substring);
// WASM_TEST_HANDLER(test_string, substring_out_of_bound);
// WASM_TEST_HANDLER(test_string, concatenation_null_terminated);
// WASM_TEST_HANDLER(test_string, concatenation_non_null_terminated);
// WASM_TEST_HANDLER(test_string, assign);
// WASM_TEST_HANDLER(test_string, comparison_operator);
// WASM_TEST_HANDLER(test_string, print_null_terminated);
// WASM_TEST_HANDLER(test_string, print_non_null_terminated);
// WASM_TEST_HANDLER(test_string, print_unicode);
// WASM_TEST_HANDLER(test_string, valid_utf8);
// WASM_TEST_HANDLER(test_string, invalid_utf8);
// WASM_TEST_HANDLER(test_string, string_literal);
//
// // test fixed_point
// WASM_TEST_HANDLER(test_fixedpoint, create_instances);
// WASM_TEST_HANDLER(test_fixedpoint, test_addition);
// WASM_TEST_HANDLER(test_fixedpoint, test_subtraction);
// WASM_TEST_HANDLER(test_fixedpoint, test_multiplication);
// WASM_TEST_HANDLER(test_fixedpoint, test_division);
//
//
// // test double
// WASM_TEST_HANDLER(test_real, create_instances);
// WASM_TEST_HANDLER(test_real, test_addition);
// WASM_TEST_HANDLER(test_real, test_multiplication);
// WASM_TEST_HANDLER(test_real, test_division);
//
// // test account
// WASM_TEST_HANDLER(test_account, test_balance_acc1);
//
//test_math
WASM_TEST_HANDLER(test_math, test_multeq);
WASM_TEST_HANDLER(test_math, test_diveq);
WASM_TEST_HANDLER(test_math, test_i64_to_double);
WASM_TEST_HANDLER(test_math, test_double_to_i64);
WASM_TEST_HANDLER(test_math, test_diveq_by_0);
WASM_TEST_HANDLER(test_math, test_double_api);
WASM_TEST_HANDLER(test_math, test_double_api_div_0);
//test crypto
WASM_TEST_HANDLER(test_crypto, test_recover_key);
WASM_TEST_HANDLER(test_crypto, test_recover_key_assert_true);
WASM_TEST_HANDLER(test_crypto, test_recover_key_assert_false);
WASM_TEST_HANDLER(test_crypto, test_sha1);
WASM_TEST_HANDLER(test_crypto, test_sha256);
WASM_TEST_HANDLER(test_crypto, test_sha512);
WASM_TEST_HANDLER(test_crypto, test_ripemd160);
WASM_TEST_HANDLER(test_crypto, sha1_no_data);
WASM_TEST_HANDLER(test_crypto, sha256_no_data);
WASM_TEST_HANDLER(test_crypto, sha512_no_data);
WASM_TEST_HANDLER(test_crypto, ripemd160_no_data);
WASM_TEST_HANDLER(test_crypto, sha256_null);
WASM_TEST_HANDLER(test_crypto, assert_sha256_false);
WASM_TEST_HANDLER(test_crypto, assert_sha256_true);
WASM_TEST_HANDLER(test_crypto, assert_sha1_false);
WASM_TEST_HANDLER(test_crypto, assert_sha1_true);
WASM_TEST_HANDLER(test_crypto, assert_sha512_false);
WASM_TEST_HANDLER(test_crypto, assert_sha512_true);
WASM_TEST_HANDLER(test_crypto, assert_ripemd160_false);
WASM_TEST_HANDLER(test_crypto, assert_ripemd160_true);
//test transaction
WASM_TEST_HANDLER(test_transaction, test_tapos_block_num);
WASM_TEST_HANDLER(test_transaction, test_tapos_block_prefix);
WASM_TEST_HANDLER(test_transaction, send_action);
WASM_TEST_HANDLER(test_transaction, send_action_inline_fail);
WASM_TEST_HANDLER(test_transaction, send_action_empty);
WASM_TEST_HANDLER(test_transaction, send_action_large);
WASM_TEST_HANDLER(test_transaction, send_action_recurse);
WASM_TEST_HANDLER(test_transaction, test_read_transaction);
WASM_TEST_HANDLER(test_transaction, test_transaction_size);
WASM_TEST_HANDLER(test_transaction, send_transaction);
WASM_TEST_HANDLER(test_transaction, send_transaction_empty);
WASM_TEST_HANDLER(test_transaction, send_transaction_large);
WASM_TEST_HANDLER(test_transaction, send_action_sender);
//test chain
WASM_TEST_HANDLER(test_chain, test_activeprods);
// test fixed_point
WASM_TEST_HANDLER(test_fixedpoint, create_instances);
WASM_TEST_HANDLER(test_fixedpoint, test_addition);
WASM_TEST_HANDLER(test_fixedpoint, test_subtraction);
WASM_TEST_HANDLER(test_fixedpoint, test_multiplication);
WASM_TEST_HANDLER(test_fixedpoint, test_division);
WASM_TEST_HANDLER(test_fixedpoint, test_division_by_0);
// test double
WASM_TEST_HANDLER(test_real, create_instances);
WASM_TEST_HANDLER(test_real, test_addition);
WASM_TEST_HANDLER(test_real, test_multiplication);
WASM_TEST_HANDLER(test_real, test_division);
WASM_TEST_HANDLER(test_real, test_division_by_0);
// test checktime
WASM_TEST_HANDLER(test_checktime, checktime_pass);
WASM_TEST_HANDLER(test_checktime, checktime_failure);
//unhandled test call
eosio_assert(false, "Unknown Test");
}
}
......@@ -32,95 +32,102 @@ struct dummy_action {
int c; //4
};
struct u128_msg {
struct u128_action {
unsigned __int128 values[3]; //16*3
};
#pragma pack(pop)
static_assert( sizeof(dummy_action) == 13 , "unexpected packing" );
static_assert( sizeof(u128_msg) == 16*3 , "unexpected packing" );
static_assert( sizeof(u128_action) == 16*3 , "unexpected packing" );
struct test_types {
static unsigned int types_size();
static unsigned int char_to_symbol();
static unsigned int string_to_name();
static unsigned int name_class();
static void types_size();
static void char_to_symbol();
static void string_to_name();
static void name_class();
};
struct test_print {
static void test_prints();
static void test_prints_l();
static void test_printi();
static void test_printi128();
static void test_printn();
};
#define DUMMY_MESSAGE_DEFAULT_A 0x45
#define DUMMY_MESSAGE_DEFAULT_B 0xab11cd1244556677
#define DUMMY_MESSAGE_DEFAULT_C 0x7451ae12
#define DUMMY_ACTION_DEFAULT_A 0x45
#define DUMMY_ACTION_DEFAULT_B 0xab11cd1244556677
#define DUMMY_ACTION_DEFAULT_C 0x7451ae12
struct test_action {
static void read_action_normal();
static void read_action_to_0();
static void read_action_to_64k();
static unsigned int require_notice();
static unsigned int require_auth();
static void require_notice();
static void require_auth();
static void assert_false();
static void assert_true();
static unsigned int now();
static void now();
static void test_abort();
static void test_current_receiver();
static void test_current_sender();
static void test_publication_time();
};
struct test_math {
static unsigned int test_multeq_i128();
static unsigned int test_diveq_i128();
static unsigned int test_diveq_i128_by_0();
static unsigned int test_double_api();
static unsigned int test_double_api_div_0();
static void test_multeq();
static void test_diveq();
static void test_diveq_by_0();
static void test_double_api();
static void test_double_api_div_0();
static void test_i64_to_double();
static void test_double_to_i64();
};
struct test_db {
static unsigned int key_i64_general();
static unsigned int key_i64_remove_all();
static unsigned int key_i64_small_load();
static unsigned int key_i64_small_store();
static unsigned int key_i64_store_scope();
static unsigned int key_i64_remove_scope();
static unsigned int key_i64_not_found();
static unsigned int key_i64_front_back();
static unsigned int key_i128i128_general();
static unsigned int key_i64i64i64_general();
static unsigned int key_str_general();
static unsigned int key_str_table();
static unsigned int key_str_setup_limit();
static unsigned int key_str_min_exceed_limit();
static unsigned int key_str_under_limit();
static unsigned int key_str_available_space_exceed_limit();
static unsigned int key_str_another_under_limit();
static unsigned int key_i64_setup_limit();
static unsigned int key_i64_min_exceed_limit();
static unsigned int key_i64_under_limit();
static unsigned int key_i64_available_space_exceed_limit();
static unsigned int key_i64_another_under_limit();
static unsigned int key_i128i128_setup_limit();
static unsigned int key_i128i128_min_exceed_limit();
static unsigned int key_i128i128_under_limit();
static unsigned int key_i128i128_available_space_exceed_limit();
static unsigned int key_i128i128_another_under_limit();
static unsigned int key_i64i64i64_setup_limit();
static unsigned int key_i64i64i64_min_exceed_limit();
static unsigned int key_i64i64i64_under_limit();
static unsigned int key_i64i64i64_available_space_exceed_limit();
static unsigned int key_i64i64i64_another_under_limit();
static void key_i64_general();
static void key_i64_remove_all();
static void key_i64_small_load();
static void key_i64_small_store();
static void key_i64_store_scope();
static void key_i64_remove_scope();
static void key_i64_not_found();
static void key_i64_front_back();
static void key_i128i128_general();
static void key_i64i64i64_general();
static void key_str_general();
static void key_str_table();
static void key_str_setup_limit();
static void key_str_min_exceed_limit();
static void key_str_under_limit();
static void key_str_available_space_exceed_limit();
static void key_str_another_under_limit();
static void key_i64_setup_limit();
static void key_i64_min_exceed_limit();
static void key_i64_under_limit();
static void key_i64_available_space_exceed_limit();
static void key_i64_another_under_limit();
static void key_i128i128_setup_limit();
static void key_i128i128_min_exceed_limit();
static void key_i128i128_under_limit();
static void key_i128i128_available_space_exceed_limit();
static void key_i128i128_another_under_limit();
static void key_i64i64i64_setup_limit();
static void key_i64i64i64_min_exceed_limit();
static void key_i64i64i64_under_limit();
static void key_i64i64i64_available_space_exceed_limit();
static void key_i64i64i64_another_under_limit();
static void primary_i64_general();
static void primary_i64_lowerbound();
static void primary_i64_upperbound();
static void idx64_general();
static void idx64_lowerbound();
static void idx64_upperbound();
......@@ -136,69 +143,102 @@ struct test_multi_index {
};
struct test_crypto {
static unsigned int test_sha256();
static unsigned int sha256_no_data();
static unsigned int asert_sha256_false();
static unsigned int asert_sha256_true();
static unsigned int asert_no_data();
static void test_recover_key();
static void test_recover_key_assert_true();
static void test_recover_key_assert_false();
static void test_sha1();
static void test_sha256();
static void test_sha512();
static void test_ripemd160();
static void sha1_no_data();
static void sha256_no_data();
static void sha512_no_data();
static void ripemd160_no_data();
static void sha256_null();
static void assert_sha256_false();
static void assert_sha1_false();
static void assert_sha512_false();
static void assert_ripemd160_false();
static void assert_sha256_true();
static void assert_sha1_true();
static void assert_sha512_true();
static void assert_ripemd160_true();
};
struct test_transaction {
static unsigned int send_message();
static unsigned int send_message_empty();
static unsigned int send_message_max();
static unsigned int send_message_large();
static unsigned int send_message_recurse();
static unsigned int send_message_inline_fail();
static unsigned int send_transaction();
static unsigned int send_transaction_empty();
static unsigned int send_transaction_max();
static unsigned int send_transaction_large();
static void test_tapos_block_num();
static void test_tapos_block_prefix();
static void send_action();
static void send_action_empty();
static void send_action_max();
static void send_action_large();
static void send_action_recurse();
static void send_action_inline_fail();
static void test_read_transaction();
static void test_transaction_size();
static void send_transaction();
static void send_transaction_empty();
static void send_transaction_max();
static void send_transaction_large();
static void send_action_sender();
};
struct test_chain {
static unsigned int test_activeprods();
};
struct test_string {
static unsigned int construct_with_size();
static unsigned int construct_with_data();
static unsigned int construct_with_data_copied();
static unsigned int construct_with_data_partially();
static unsigned int copy_constructor();
static unsigned int assignment_operator();
static unsigned int index_operator();
static unsigned int index_out_of_bound();
static unsigned int substring();
static unsigned int substring_out_of_bound();
static unsigned int concatenation_null_terminated();
static unsigned int concatenation_non_null_terminated();
static unsigned int assign();
static unsigned int comparison_operator();
static unsigned int print_null_terminated();
static unsigned int print_non_null_terminated();
static unsigned int print_unicode();
static unsigned int valid_utf8();
static unsigned int invalid_utf8();
static unsigned int string_literal();
static void test_activeprods();
};
struct test_fixedpoint {
static unsigned int create_instances();
static unsigned int test_addition();
static unsigned int test_subtraction();
static unsigned int test_multiplication();
static unsigned int test_division();
static void create_instances();
static void test_addition();
static void test_subtraction();
static void test_multiplication();
static void test_division();
static void test_division_by_0();
};
struct test_real {
static unsigned int create_instances();
static unsigned int test_addition();
static unsigned int test_multiplication();
static unsigned int test_division();
static void create_instances();
static void test_addition();
static void test_multiplication();
static void test_division();
static void test_division_by_0();
};
struct test_compiler_builtins {
static void test_multi3();
static void test_divti3();
static void test_divti3_by_0();
static void test_udivti3();
static void test_udivti3_by_0();
static void test_modti3();
static void test_modti3_by_0();
static void test_umodti3();
static void test_umodti3_by_0();
static void test_lshlti3();
static void test_lshrti3();
static void test_ashlti3();
static void test_ashrti3();
};
struct test_extended_memory {
static void test_initial_buffer();
static void test_page_memory();
static void test_page_memory_exceeded();
static void test_page_memory_negative_bytes();
};
struct test_memory {
static void test_memory_allocs();
static void test_memory_hunk();
static void test_memory_hunks();
static void test_memory_hunks_disjoint();
static void test_memset_memcpy();
static void test_memcpy_overlap_start();
static void test_memcpy_overlap_end();
static void test_memcmp();
};
struct test_account {
static unsigned int test_balance_acc1();
struct test_checktime {
static void checktime_pass();
static void checktime_failure();
};
......@@ -4,7 +4,7 @@
*/
#include <eosiolib/action.h>
#include <eosiolib/chain.h>
#include <eosiolib/eosio.hpp>
#include "test_api.hpp"
#pragma pack(push, 1)
......@@ -14,18 +14,15 @@ struct producers {
};
#pragma pack(pop)
unsigned int test_chain::test_activeprods() {
producers msg_prods;
read_action(&msg_prods, sizeof(producers));
WASM_ASSERT(msg_prods.len == 21, "producers.len != 21");
void test_chain::test_activeprods() {
producers act_prods;
read_action(&act_prods, sizeof(producers));
eosio_assert(act_prods.len == 21, "producers.len != 21");
producers api_prods;
get_active_producers(api_prods.producers, sizeof(account_name)*21);
for( int i = 0; i < 21 ; ++i ) {
WASM_ASSERT(api_prods.producers[i] == msg_prods.producers[i], "Active producer");
}
return WASM_TEST_PASS;
for( int i = 0; i < 21 ; ++i )
eosio_assert(api_prods.producers[i] == act_prods.producers[i], "Active producer");
}
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/eosio.hpp>
#include "test_api.hpp"
void test_checktime::checktime_pass() {
int p = 0;
for ( int i = 0; i < 10000; i++ )
p += i;
eosio::print(p);
}
void test_checktime::checktime_failure() {
int p = 0;
for ( unsigned long long i = 0; i < 10000000000000000000ULL; i++ )
for ( unsigned long long j = 0; i < 10000000000000000000ULL; i++ )
p += i+j;
eosio::print(p);
}
/**
* @file test_compiler_builtins.cpp
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/compiler_builtins.h>
#include "test_api.hpp"
using namespace eosio;
unsigned __int128 operator "" _ULLL( const char* lit ) {
__int128 ret = 0;
size_t i = 0;
bool sign = false;
if (lit[i] == '-') {
++i;
sign = true;
}
if (lit[i] == '+')
++i;
for (; lit[i] != '\0' ; ++i) {
const char c = lit[i];
ret *= 10;
ret += c - '0';
}
if (sign)
ret *= -1;
return ret;
}
__int128 operator "" _LLL( const char* lit ) {
__int128 ret = 0;
size_t i = 0;
bool sign = false;
if (lit[i] == '-') {
++i;
sign = true;
}
if (lit[i] == '+')
++i;
for (; lit[i] != '\0' ; ++i) {
const char c = lit[i];
ret *= 10;
ret += c - '0';
}
if (sign)
ret *= -1;
return ret;
}
void test_compiler_builtins::test_multi3() {
/*
* tests for negative values
*/
__int128 res = 0;
__int128 lhs_a = -30;
__int128 rhs_a = 100;
__int128 lhs_b = 100;
__int128 rhs_b = -30;
__multi3( res, lhs_a, ( lhs_a >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == -3000, "__multi3 result should be -3000" );
__multi3( res, lhs_b, ( lhs_b >> 64 ), rhs_b, ( rhs_b >> 64 ) );
eosio_assert( res == -3000, "__multi3 result should be -3000" );
__multi3( res, lhs_a, ( lhs_a >> 64 ), rhs_b, ( rhs_b >> 64 ) );
eosio_assert( res == 900, "__multi3 result should be 900" );
/*
* test for positive values
*/
__multi3( res, lhs_b, ( lhs_b >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 10000, "__multi3 result should be 10000" );
/*
* test identity
*/
__multi3( res, 1, 0, rhs_a, rhs_a >> 64 );
eosio_assert( res == 100, "__multi3 result should be 100" );
__multi3( res, 1, 0, rhs_b, rhs_b >> 64 );
eosio_assert( res == -30, "__multi3 result should be -30" );
}
void test_compiler_builtins::test_divti3() {
/*
* test for negative values
*/
__int128 res = 0;
__int128 lhs_a = -30;
__int128 rhs_a = 100;
__int128 lhs_b = 100;
__int128 rhs_b = -30;
__divti3( res, lhs_a, ( lhs_a >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 0, "__divti3 result should be 0" );
__divti3( res, lhs_b, ( lhs_b >> 64 ), rhs_b, ( rhs_b >> 64 ) );
eosio_assert( res == -3, "__divti3 result should be -3" );
__divti3( res, lhs_a, ( lhs_a >> 64 ), rhs_b, ( rhs_b >> 64 ) );
eosio_assert( res == 1, "__divti3 result should be 1" );
/*
* test for positive values
*/
__int128 lhs_c = 3333;
__int128 rhs_c = 3333;
__divti3( res, lhs_b, ( lhs_b >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 1, "__divti3 result should be 1" );
__divti3( res, lhs_b, ( lhs_b >> 64 ), rhs_c, ( rhs_c >> 64 ) );
eosio_assert( res == 0, "__divti3 result should be 0" );
__divti3( res, lhs_c, ( lhs_c >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 33, "__divti3 result should be 33" );
/*
* test identity
*/
__divti3( res, lhs_b, ( lhs_b >> 64 ), 1, 0 );
eosio_assert( res == 100, "__divti3 result should be 100" );
__divti3( res, lhs_a, ( lhs_a >> 64 ), 1, 0 );
eosio_assert( res == -30, "__divti3 result should be -30" );
}
void test_compiler_builtins::test_divti3_by_0() {
__int128 res = 0;
__divti3( res, 100, 0, 0, 0 );
eosio_assert( false, "Should have eosio_asserted" );
}
void test_compiler_builtins::test_udivti3() {
/*
* test for negative values
*/
unsigned __int128 res = 0;
unsigned __int128 lhs_a = -30;
unsigned __int128 rhs_a = 100;
unsigned __int128 lhs_b = 100;
unsigned __int128 rhs_b = -30;
__udivti3( res, lhs_a, ( lhs_a >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 3402823669209384634633746074317682114_ULLL, "__udivti3 result should be 0" );
__udivti3( res, lhs_b, ( lhs_b >> 64 ), rhs_b, ( rhs_b >> 64 ) );
eosio_assert( res == 0, "__udivti3 result should be 0" );
__udivti3( res, lhs_a, ( lhs_a >> 64 ), rhs_b, ( rhs_b >> 64 ) );
eosio_assert( res == 1, "__udivti3 result should be 1" );
/*
* test for positive values
*/
__int128 lhs_c = 3333;
__int128 rhs_c = 3333;
__udivti3( res, lhs_b, ( lhs_b >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 1, "__divti3 result should be 1" );
__udivti3( res, lhs_b, ( lhs_b >> 64 ), rhs_c, ( rhs_c >> 64 ) );
eosio_assert( res == 0, "__divti3 result should be 0" );
__udivti3( res, lhs_c, ( lhs_c >> 64 ), rhs_a, ( rhs_a >> 64 ) );
eosio_assert( res == 33, "__divti3 result should be 33" );
/*
* test identity
*/
__udivti3( res, lhs_b, ( lhs_b >> 64 ), 1, 0 );
eosio_assert( res == 100, "__divti3 result should be 100" );
__udivti3( res, lhs_a, ( lhs_a >> 64 ), 1, 0 );
eosio_assert( res == -30, "__divti3 result should be -30" );
}
void test_compiler_builtins::test_udivti3_by_0() {
unsigned __int128 res = 0;
__udivti3( res, 100, 0, 0, 0 );
eosio_assert( false, "Should have eosio_asserted" );
}
void test_compiler_builtins::test_lshlti3() {
__int128 res = 0;
__int128 val = 1;
__int128 test_res = 0;
test_res = 0x8000000000000000;
test_res <<= 1;
__lshlti3( res, val, val >> 64, 0 );
eosio_assert( res == 1, "__lshlti3 result should be 1" );
__lshlti3( res, val, val >> 64, 1 );
eosio_assert( res == ( 1 << 1 ), "__lshlti3 result should be 2" );
__lshlti3( res, val, ( val >> 64 ), 31 );
eosio_assert( res == 2147483648_ULLL, "__lshlti3 result should be 2^31" );
__lshlti3( res, val, ( val >> 64 ), 63 );
eosio_assert( res == 9223372036854775808_ULLL, "__lshlti3 result should be 2^63" );
__lshlti3( res, val, ( val >> 64 ), 64 );
eosio_assert( res == test_res, "__lshlti3 result should be 2^64" );
__lshlti3( res, val, ( val >> 64 ), 127 );
test_res <<= 63;
eosio_assert( res == test_res, "__lshlti3 result should be 2^127" );
__lshlti3( res, val, ( val >> 64 ), 128 );
test_res <<= 1;
//should rollover
eosio_assert( res == test_res, "__lshlti3 result should be 2^128" );
}
void test_compiler_builtins::test_ashlti3() {
__int128 res = 0;
__int128 val = 1;
__int128 test_res = 0;
test_res = 0x8000000000000000;
test_res <<= 1;
__ashlti3( res, val, val >> 64, 0 );
eosio_assert( res == 1, "__ashlti3 result should be 1" );
__ashlti3( res, val, val >> 64, 1 );
eosio_assert( res == (1 << 1), "__ashlti3 result should be 2" );
__ashlti3( res, val, (val >> 64), 31 );
eosio_assert( res == 2147483648_ULLL, "__ashlti3 result should be 2^31" );
__ashlti3( res, val, (val >> 64), 63 );
eosio_assert( res == 9223372036854775808_ULLL, "__ashlti3 result should be 2^63" );
__ashlti3( res, val, (val >> 64), 64 );
eosio_assert( res == test_res, "__ashlti3 result should be 2^64" );
__ashlti3( res, val, (val >> 64), 127 );
test_res <<= 63;
eosio_assert( res == test_res, "__ashlti3 result should be 2^127" );
__ashlti3( res, val, (val >> 64), 128 );
test_res <<= 1;
//should rollover
eosio_assert( res == test_res, "__ashlti3 result should be 2^128" );
}
void test_compiler_builtins::test_lshrti3() {
__int128 res = 0;
__int128 val = 0x8000000000000000;
__int128 test_res = 0x8000000000000000;
val <<= 64;
test_res <<= 64;
__lshrti3( res, val, (val >> 64), 0 );
eosio_assert( res == test_res, "__lshrti3 result should be 2^127" );
__lshrti3( res, val, (val >> 64), 1 );
eosio_assert( res == 85070591730234615865843651857942052864_ULLL, "__lshrti3 result should be 2^126" );
__lshrti3( res, val, (val >> 64), 63 );
eosio_assert( res == 18446744073709551616_ULLL, "__lshrti3 result should be 2^64" );
__lshrti3( res, val, (val >> 64), 64 );
eosio_assert( res == 9223372036854775808_ULLL, "__lshrti3 result should be 2^63" );
__lshrti3( res, val, (val >> 64), 96 );
eosio_assert( res == 2147483648_ULLL, "__lshrti3 result should be 2^31" );
__lshrti3( res, val, (val >> 64), 127 );
eosio_assert( res == 0x1, "__lshrti3 result should be 2^0" );
}
void test_compiler_builtins::test_ashrti3() {
__int128 res = 0;
__int128 test = 1;
__int128 val = -170141183460469231731687303715884105728_LLL;
test <<= 127;
__ashrti3( res, val, (val >> 64), 0 );
eosio_assert( res == -170141183460469231731687303715884105728_LLL, "__ashrti3 result should be -2^127" );
__ashrti3(res, val, (val >> 64), 1 );
eosio_assert( res == -85070591730234615865843651857942052864_LLL, "__ashrti3 result should be -2^126" );
__ashrti3(res, val, (val >> 64), 2 );
eosio_assert( res == test >> 2, "__ashrti3 result should be -2^125" );
__ashrti3( res, val, (val >> 64), 64 );
eosio_assert( res == test >> 64, "__ashrti3 result should be -2^63" );
__ashrti3( res, val, (val >> 64), 95 );
eosio_assert( res == test >> 95, "__ashrti3 result should be -2^31" );
__ashrti3( res, val, (val >> 64), 127 );
eosio_assert( res == test >> 127, "__ashrti3 result should be -2^0" );
}
void test_compiler_builtins::test_modti3() {
__int128 res = 0;
__int128 lhs_a = -30;
__int128 rhs_a = 100;
__int128 lhs_b = 30;
__int128 rhs_b = -100;
__modti3( res, lhs_a, lhs_a >> 64, rhs_a, rhs_a >> 64 );
eosio_assert( res == -30, "__modti3 result should be -30" );
__modti3( res, lhs_b, lhs_b >> 64, rhs_b, rhs_b >> 64 );
eosio_assert( res == 30, "__modti3 result should be 30" );
__modti3( res, lhs_a, lhs_a >> 64, rhs_b, rhs_b >> 64 );
eosio_assert( res == -30, "__modti3 result should be -30" );
__modti3( res, rhs_a, rhs_a >> 64, lhs_b, lhs_b >> 64 );
eosio_assert( res == 10, "__modti3 result should be 10" );
__modti3( res, rhs_a, rhs_a >> 64, rhs_b, rhs_b >> 64 );
eosio_assert( res == 0, "__modti3 result should be 0" );
__modti3( res, rhs_a, rhs_a >> 64, rhs_a, rhs_a >> 64 );
eosio_assert( res == 0, "__modti3 result should be 0" );
__modti3( res, 0, 0, rhs_a, rhs_a >> 64 );
eosio_assert( res == 0, "__modti3 result should be 0" );
}
void test_compiler_builtins::test_modti3_by_0() {
__int128 res = 0;
__int128 lhs = 100;
__modti3( res, lhs, lhs >> 64, 0, 0 );
eosio_assert( false, "should have thrown an error" );
}
void test_compiler_builtins::test_umodti3() {
unsigned __int128 res = 0;
unsigned __int128 lhs_a = -30;
unsigned __int128 rhs_a = 100;
unsigned __int128 lhs_b = 30;
unsigned __int128 rhs_b = -100;
__umodti3( res, lhs_a, lhs_a >> 64, rhs_a, rhs_a >> 64 );
eosio_assert( res == -30, "__modti3 result should be -30" );
__umodti3( res, lhs_b, lhs_b >> 64, rhs_b, rhs_b >> 64 );
eosio_assert( res == 30, "__modti3 result should be 30" );
__umodti3( res, lhs_a, lhs_a >> 64, rhs_b, rhs_b >> 64 );
eosio_assert( res == -30, "__modti3 result should be -30" );
__umodti3( res, rhs_a, rhs_a >> 64, lhs_b, lhs_b >> 64 );
eosio_assert( res == 10, "__modti3 result should be 10" );
__umodti3( res, rhs_a, rhs_a >> 64, rhs_b, rhs_b >> 64 );
eosio_assert( res == 0, "__modti3 result should be 0" );
__umodti3( res, rhs_a, rhs_a >> 64, rhs_a, rhs_a >> 64 );
eosio_assert( res == 0, "__modti3 result should be 0" );
__umodti3( res, 0, 0, rhs_a, rhs_a >> 64 );
eosio_assert( res == 0, "__modti3 result should be 0" );
}
void test_compiler_builtins::test_umodti3_by_0() {
unsigned __int128 res = 0;
unsigned __int128 lhs = 100;
__umodti3( res, lhs, lhs >> 64, 0, 0 );
eosio_assert( false, "should have thrown an error" );
}
......@@ -2,51 +2,168 @@
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/eos.hpp>
#include <eosiolib/eosio.hpp>
#include <eosiolib/crypto.h>
#include <eosiolib/print.hpp>
#include "test_api.hpp"
#define WASM_TEST_FAIL 1
static const char test1[] = "abc";
static const unsigned char test1_ok[] = {
static const unsigned char test1_ok_1[] = {
0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81,
0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50,
0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d
};
static const unsigned char test1_ok_256[] = {
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
};
static const unsigned char test1_ok_512[] = {
0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
};
static const unsigned char test1_ok_ripe[] = {
0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a,
0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87,
0xf1, 0x5a, 0x0b, 0xfc
};
const char test2[] = "";
const unsigned char test2_ok[] = {
static const unsigned char test2_ok_1[] = {
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60,
0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
};
const unsigned char test2_ok_256[] = {
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
};
const unsigned char test2_ok_512[] = {
0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd,
0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07,
0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc,
0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce,
0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0,
0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f,
0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81,
0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
};
const unsigned char test2_ok_ripe[] = {
0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54,
0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48,
0xb2, 0x25, 0x8d, 0x31
};
static const char test3[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
static const unsigned char test3_ok[] = {
static const unsigned char test3_ok_1[] = {
0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2,
0x6e, 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51,
0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1
};
static const unsigned char test3_ok_256[] = {
0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1
};
static const unsigned char test3_ok_512[] = {
0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45
};
static const unsigned char test3_ok_ripe[] = {
0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88,
0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a,
0xda, 0x62, 0xeb, 0x2b
};
static const char test4[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
static const unsigned char test4_ok[] = {
static const unsigned char test4_ok_1[] = {
0xa4, 0x9b, 0x24, 0x46, 0xa0, 0x2c, 0x64,
0x5b, 0xf4, 0x19, 0xf9, 0x95, 0xb6, 0x70,
0x91, 0x25, 0x3a, 0x04, 0xa2, 0x59
};
static const unsigned char test4_ok_256[] = {
0xcf, 0x5b, 0x16, 0xa7, 0x78, 0xaf, 0x83, 0x80,
0x03, 0x6c, 0xe5, 0x9e, 0x7b, 0x04, 0x92, 0x37,
0x0b, 0x24, 0x9b, 0x11, 0xe8, 0xf0, 0x7a, 0x51,
0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1
};
static const unsigned char test4_ok_512[] = {
0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09
};
static const unsigned char test4_ok_ripe[] = {
0x6f, 0x3f, 0xa3, 0x9b, 0x6b, 0x50, 0x3c, 0x38,
0x4f, 0x91, 0x9a, 0x49, 0xa7, 0xaa, 0x5c, 0x2c,
0x08, 0xbd, 0xfb, 0x45
};
static const char test5[] = "message digest";
static const unsigned char test5_ok[] = {
static const unsigned char test5_ok_1[] = {
0xc1, 0x22, 0x52, 0xce, 0xda, 0x8b, 0xe8,
0x99, 0x4d, 0x5f, 0xa0, 0x29, 0x0a, 0x47,
0x23, 0x1c, 0x1d, 0x16, 0xaa, 0xe3
};
static const unsigned char test5_ok_256[] = {
0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e,
0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad,
0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef,
0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50
};
static const unsigned char test5_ok_512[] = {
0x10, 0x7d, 0xbf, 0x38, 0x9d, 0x9e, 0x9f, 0x71,
0xa3, 0xa9, 0x5f, 0x6c, 0x05, 0x5b, 0x92, 0x51,
0xbc, 0x52, 0x68, 0xc2, 0xbe, 0x16, 0xd6, 0xc1,
0x34, 0x92, 0xea, 0x45, 0xb0, 0x19, 0x9f, 0x33,
0x09, 0xe1, 0x64, 0x55, 0xab, 0x1e, 0x96, 0x11,
0x8e, 0x8a, 0x90, 0x5d, 0x55, 0x97, 0xb7, 0x20,
0x38, 0xdd, 0xb3, 0x72, 0xa8, 0x98, 0x26, 0x04,
0x6d, 0xe6, 0x66, 0x87, 0xbb, 0x42, 0x0e, 0x7c
};
static const unsigned char test5_ok_ripe[] = {
0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5,
0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa,
0x21, 0x59, 0x5f, 0x36
};
extern "C" {
uint32_t my_strlen(const char *str) {
uint32_t len = 0;
......@@ -68,49 +185,158 @@ extern "C" {
}
unsigned int test_crypto::test_sha256() {
struct sig_hash_key {
checksum256 hash;
public_key pk;
signature sig;
};
void test_crypto::test_recover_key_assert_true() {
sig_hash_key sh;
int read = read_action( (char*)&sh, sizeof(sh) );
public_key public_key;
assert_recover_key( &sh.hash, (const char*)&sh.sig, sizeof(sh.sig), (const char*)&sh.pk, sizeof(sh.pk) );
}
void test_crypto::test_recover_key_assert_false() {
sig_hash_key sh;
int read = read_action( (char*)&sh, sizeof(sh) );
assert_recover_key( &sh.hash, (const char*)&sh.sig, sizeof(sh.sig), (const char*)&sh.pk, sizeof(sh.pk) );
eosio_assert( false, "should have thrown an error" );
}
void test_crypto::test_recover_key() {
sig_hash_key sh;
int read = read_action( (char*)&sh, sizeof(sh) );
public_key pk;
int recovered = recover_key( &sh.hash, (const char*)&sh.sig, sizeof(sh.sig), pk.data, sizeof(pk) );
for ( int i=0; i < sizeof(pk); i++ )
if ( pk.data[i] != sh.pk.data[i] )
eosio_assert( false, "public key does not match" );
}
void test_crypto::test_sha1() {
checksum160 tmp;
checksum tmp;
sha1( (char *)test1, my_strlen(test1), &tmp );
eosio_assert( my_memcmp((void *)test1_ok_1, &tmp, sizeof(checksum160)), "sha1 test1" );
sha1( (char *)test3, my_strlen(test3), &tmp );
eosio_assert( my_memcmp((void *)test3_ok_1, &tmp, sizeof(checksum160)), "sha1 test3" );
sha1( (char *)test4, my_strlen(test4), &tmp );
eosio_assert( my_memcmp((void *)test4_ok_1, &tmp, sizeof(checksum160)), "sha1 test4" );
sha1( (char *)test5, my_strlen(test5), &tmp );
eosio_assert( my_memcmp((void *)test5_ok_1, &tmp, sizeof(checksum160)), "sha1 test5" );
}
void test_crypto::test_sha256() {
checksum256 tmp;
sha256( (char *)test1, my_strlen(test1), &tmp );
WASM_ASSERT( my_memcmp((void *)test1_ok, &tmp, sizeof(checksum)), "sha256 test1" );
eosio_assert( my_memcmp((void *)test1_ok_256, &tmp, sizeof(checksum256)), "sha256 test1" );
sha256( (char *)test3, my_strlen(test3), &tmp );
WASM_ASSERT( my_memcmp((void *)test3_ok, &tmp, sizeof(checksum)), "sha256 test3" );
eosio_assert( my_memcmp((void *)test3_ok_256, &tmp, sizeof(checksum256)), "sha256 test3" );
sha256( (char *)test4, my_strlen(test4), &tmp );
WASM_ASSERT( my_memcmp((void *)test4_ok, &tmp, sizeof(checksum)), "sha256 test4" );
eosio_assert( my_memcmp((void *)test4_ok_256, &tmp, sizeof(checksum256)), "sha256 test4" );
sha256( (char *)test5, my_strlen(test5), &tmp );
WASM_ASSERT( my_memcmp((void *)test5_ok, &tmp, sizeof(checksum)), "sha256 test5" );
eosio_assert( my_memcmp((void *)test5_ok_256, &tmp, sizeof(checksum256)), "sha256 test5" );
}
void test_crypto::test_sha512() {
checksum512 tmp;
sha512( (char *)test1, my_strlen(test1), &tmp );
eosio_assert( my_memcmp((void *)test1_ok_512, &tmp, sizeof(checksum512)), "sha512 test1" );
return WASM_TEST_PASS;
sha512( (char *)test3, my_strlen(test3), &tmp );
eosio_assert( my_memcmp((void *)test3_ok_512, &tmp, sizeof(checksum512)), "sha512 test3" );
sha512( (char *)test4, my_strlen(test4), &tmp );
eosio_assert( my_memcmp((void *)test4_ok_512, &tmp, sizeof(checksum512)), "sha512 test4" );
sha512( (char *)test5, my_strlen(test5), &tmp );
eosio_assert( my_memcmp((void *)test5_ok_512, &tmp, sizeof(checksum512)), "sha512 test5" );
}
unsigned int test_crypto::sha256_no_data() {
void test_crypto::test_ripemd160() {
checksum160 tmp;
checksum tmp;
ripemd160( (char *)test1, my_strlen(test1), &tmp );
eosio_assert( my_memcmp((void *)test1_ok_ripe, &tmp, sizeof(checksum160)), "ripemd160 test1" );
ripemd160( (char *)test3, my_strlen(test3), &tmp );
eosio_assert( my_memcmp((void *)test3_ok_ripe, &tmp, sizeof(checksum160)), "ripemd160 test3" );
ripemd160( (char *)test4, my_strlen(test4), &tmp );
eosio_assert( my_memcmp((void *)test4_ok_ripe, &tmp, sizeof(checksum160)), "ripemd160 test4" );
ripemd160( (char *)test5, my_strlen(test5), &tmp );
eosio_assert( my_memcmp((void *)test5_ok_ripe, &tmp, sizeof(checksum160)), "ripemd160 test5" );
}
void test_crypto::sha256_null() {
checksum256 tmp;
int a = 3;
int* b = &a;
sha256(nullptr, 100, &tmp);
//eosio_assert(false, "should've thrown an error");
}
void test_crypto::sha1_no_data() {
checksum160 tmp;
sha1( (char *)test2, my_strlen(test2), &tmp );
eosio_assert( my_memcmp((void *)test2_ok_1, &tmp, sizeof(checksum160)), "sha1 test2" );
}
void test_crypto::sha256_no_data() {
checksum256 tmp;
sha256( (char *)test2, my_strlen(test2), &tmp );
WASM_ASSERT( my_memcmp((void *)test2_ok, &tmp, sizeof(checksum)), "sha256 test2" );
eosio_assert( my_memcmp((void *)test2_ok_256, &tmp, sizeof(checksum256)), "sha256 test2" );
}
void test_crypto::sha512_no_data() {
return WASM_TEST_PASS;
checksum512 tmp;
sha512( (char *)test2, my_strlen(test2), &tmp );
eosio_assert( my_memcmp((void *)test2_ok_512, &tmp, sizeof(checksum512)), "sha512 test2" );
}
unsigned int test_crypto::asert_sha256_false() {
void test_crypto::ripemd160_no_data() {
checksum160 tmp;
ripemd160( (char *)test2, my_strlen(test2), &tmp );
eosio_assert( my_memcmp((void *)test2_ok_ripe, &tmp, sizeof(checksum160)), "ripemd160 test2" );
}
void test_crypto::assert_sha256_false() {
checksum tmp;
checksum256 tmp;
sha256( (char *)test1, my_strlen(test1), &tmp );
tmp.hash[0] ^= (uint64_t)(-1);
assert_sha256( (char *)test1, my_strlen(test1), &tmp);
return WASM_TEST_FAIL;
eosio_assert(false, "should have failed");
}
unsigned int test_crypto::asert_sha256_true() {
void test_crypto::assert_sha256_true() {
checksum tmp;
checksum256 tmp;
sha256( (char *)test1, my_strlen(test1), &tmp );
assert_sha256( (char *)test1, my_strlen(test1), &tmp);
......@@ -123,14 +349,91 @@ unsigned int test_crypto::asert_sha256_true() {
sha256( (char *)test5, my_strlen(test5), &tmp );
assert_sha256( (char *)test5, my_strlen(test5), &tmp);
}
void test_crypto::assert_sha1_false() {
checksum160 tmp;
return WASM_TEST_PASS;
sha1( (char *)test1, my_strlen(test1), &tmp );
tmp.hash[0] ^= (uint64_t)(-1);
assert_sha1( (char *)test1, my_strlen(test1), &tmp);
eosio_assert(false, "should have failed");
}
unsigned int test_crypto::asert_no_data() {
void test_crypto::assert_sha1_true() {
checksum *tmp = (checksum*)test2_ok;
assert_sha256( (char *)test2, my_strlen(test2), tmp);
checksum160 tmp;
sha1( (char *)test1, my_strlen(test1), &tmp );
assert_sha1( (char *)test1, my_strlen(test1), &tmp);
return WASM_TEST_FAIL;
}
\ No newline at end of file
sha1( (char *)test3, my_strlen(test3), &tmp );
assert_sha1( (char *)test3, my_strlen(test3), &tmp);
sha1( (char *)test4, my_strlen(test4), &tmp );
assert_sha1( (char *)test4, my_strlen(test4), &tmp);
sha1( (char *)test5, my_strlen(test5), &tmp );
assert_sha1( (char *)test5, my_strlen(test5), &tmp);
}
void test_crypto::assert_sha512_false() {
checksum512 tmp;
sha512( (char *)test1, my_strlen(test1), &tmp );
tmp.hash[0] ^= (uint64_t)(-1);
assert_sha512( (char *)test1, my_strlen(test1), &tmp);
eosio_assert(false, "should have failed");
}
void test_crypto::assert_sha512_true() {
checksum512 tmp;
sha512( (char *)test1, my_strlen(test1), &tmp );
assert_sha512( (char *)test1, my_strlen(test1), &tmp);
sha512( (char *)test3, my_strlen(test3), &tmp );
assert_sha512( (char *)test3, my_strlen(test3), &tmp);
sha512( (char *)test4, my_strlen(test4), &tmp );
assert_sha512( (char *)test4, my_strlen(test4), &tmp);
sha512( (char *)test5, my_strlen(test5), &tmp );
assert_sha512( (char *)test5, my_strlen(test5), &tmp);
}
void test_crypto::assert_ripemd160_false() {
checksum160 tmp;
ripemd160( (char *)test1, my_strlen(test1), &tmp );
tmp.hash[0] ^= (uint64_t)(-1);
assert_ripemd160( (char *)test1, my_strlen(test1), &tmp);
eosio_assert(false, "should have failed");
}
void test_crypto::assert_ripemd160_true() {
checksum160 tmp;
ripemd160( (char *)test1, my_strlen(test1), &tmp );
assert_ripemd160( (char *)test1, my_strlen(test1), &tmp);
ripemd160( (char *)test3, my_strlen(test3), &tmp );
assert_ripemd160( (char *)test3, my_strlen(test3), &tmp);
ripemd160( (char *)test4, my_strlen(test4), &tmp );
assert_ripemd160( (char *)test4, my_strlen(test4), &tmp);
ripemd160( (char *)test5, my_strlen(test5), &tmp );
assert_ripemd160( (char *)test5, my_strlen(test5), &tmp);
}
此差异已折叠。
......@@ -5,6 +5,16 @@
#include <eosiolib/eosio.hpp>
#include "test_api.hpp"
using namespace eosio;
void test_print::test_prints_l() {
char ab[] = { 'a', 'b' };
const char test[] = "test";
prints_l(ab, 2);
prints_l(ab, 1);
prints_l(ab, 0);
prints_l(test, sizeof(test)-1);
}
void test_print::test_prints() {
prints("ab");
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
add_wast_executable(TARGET test_api_db
INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
LIBRARIES libc++ libc eosiolib
DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
)
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/eosio.hpp>
#include "../test_api/test_api.hpp"
#include "test_db.cpp"
extern "C" {
void init() {
}
void apply( unsigned long long code, unsigned long long action ) {
WASM_TEST_HANDLER(test_db, primary_i64_general);
WASM_TEST_HANDLER(test_db, primary_i64_lowerbound);
WASM_TEST_HANDLER(test_db, primary_i64_upperbound);
WASM_TEST_HANDLER(test_db, idx64_general);
WASM_TEST_HANDLER(test_db, idx64_lowerbound);
WASM_TEST_HANDLER(test_db, idx64_upperbound);
WASM_TEST_HANDLER(test_db, key_str_general);
//unhandled test call
eosio_assert(false, "Unknown Test");
}
}
add_wast_executable( TARGET test_api_mem
INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
LIBRARIES eosiolib
DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册