mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' of https://github.com/ethereum/solidity into develop
This commit is contained in:
commit
a10b6f92f9
4
.gitignore
vendored
4
.gitignore
vendored
@ -34,3 +34,7 @@ docs/utils/__pycache__
|
|||||||
|
|
||||||
# vim stuff
|
# vim stuff
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.idea
|
||||||
|
browse.VC.db
|
||||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "deps"]
|
||||||
|
path = deps
|
||||||
|
url = https://github.com/ethereum/cpp-dependencies
|
119
.travis.yml
119
.travis.yml
@ -1,15 +1,124 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# TravisCI configuration file for solidity.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# http://solidity.readthedocs.org
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of cpp-ethereum.
|
||||||
|
#
|
||||||
|
# cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 cpp-ethereum contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
language: cpp
|
language: cpp
|
||||||
cache: ccache
|
branches:
|
||||||
|
only:
|
||||||
|
- develop
|
||||||
|
- release
|
||||||
|
- standalone
|
||||||
|
except:
|
||||||
|
- /develop-v[0-9]/
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
env: TRAVIS_BUILD_TYPE=Debug
|
compiler: gcc
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
before_install:
|
||||||
|
- docker pull trzeci/emscripten:sdk-tag-1.35.4-64bit
|
||||||
|
env:
|
||||||
|
- TRAVIS_BUILD_TYPE=RelWithDebInfo
|
||||||
|
- ZIP_SUFFIX=ubuntu-trusty
|
||||||
|
- os: osx
|
||||||
|
osx_image: beta-xcode6.2
|
||||||
|
env:
|
||||||
|
- TRAVIS_BUILD_TYPE=RelWithDebInfo
|
||||||
|
- ZIP_SUFFIX=osx-mavericks
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode7.1
|
||||||
|
env:
|
||||||
|
- TRAVIS_BUILD_TYPE=RelWithDebInfo
|
||||||
|
- ZIP_SUFFIX=osx-yosemite
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode7.3
|
osx_image: xcode7.3
|
||||||
env: TRAVIS_BUILD_TYPE=Debug
|
env:
|
||||||
|
# The use of Debug config here ONLY for El Capitan is a workaround for "The Heisenbug"
|
||||||
|
# See https://github.com/ethereum/webthree-umbrella/issues/565
|
||||||
|
- TRAVIS_BUILD_TYPE=Debug
|
||||||
|
- ZIP_SUFFIX=osx-elcapitan
|
||||||
git:
|
git:
|
||||||
depth: 2
|
depth: 2
|
||||||
before_install: ./install_dependencies.sh
|
|
||||||
script: ./fetch_umbrella_build_and_test.sh
|
cache:
|
||||||
|
ccache: true
|
||||||
|
directories:
|
||||||
|
- build
|
||||||
|
- build-emscripten
|
||||||
|
- boost_1_57_0
|
||||||
|
- jsoncpp
|
||||||
|
- cryptopp
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ./scripts/install_deps.sh
|
||||||
|
before_script:
|
||||||
|
- ./scripts/build_emscripten.sh
|
||||||
|
- mkdir -p build
|
||||||
|
&& cd build
|
||||||
|
&& cmake .. -DCMAKE_BUILD_TYPE=$TRAVIS_BUILD_TYPE
|
||||||
|
&& make -j2
|
||||||
|
&& cd ..
|
||||||
|
&& ./scripts/release.sh $ZIP_SUFFIX
|
||||||
|
script:
|
||||||
|
# There are a variety of reliability issues with the Solidity unit-tests at the time of
|
||||||
|
# writing, so we're actually running them 3 times in a row, to try to flush all of these
|
||||||
|
# issues out as quickly as possible. See https://github.com/ethereum/solidity/issues/769
|
||||||
|
- cd $TRAVIS_BUILD_DIR && (./scripts/tests.sh || ./scripts/tests.sh || ./scripts/tests.sh)
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- ENCRYPTION_LABEL="296c219a3f41"
|
||||||
|
|
||||||
|
# This is the deploy target for the native build (Linux and macOS)
|
||||||
|
# which generates development ZIPs per commit. We are in agreement
|
||||||
|
# that this is probably noisy overkill, so will want to renable this
|
||||||
|
# functionality wrapped in some conditionals so that it only runs
|
||||||
|
# when building the 'release' branch.
|
||||||
|
#
|
||||||
|
#deploy:
|
||||||
|
# provider: releases
|
||||||
|
# api_key:
|
||||||
|
# secure: mGeDrlCbhPNQVqrk5wSqFZe/7C5HUIBWcZECJcFrEldN6ELj3a8mhDX9EWebidyFmZsf3ipKVMycJtXZHlH2kVZ0nZdRulq4bYhLiUFRaFQCHMW35dml5mxO/FPp+jhhZaylDUx+cI6AULbj8DvNFqSCfjx8qimRhJjRY4JHeG71N6g5+LU2/dA01D4Y97BUbQ5dYcmEyuEsriSpXOElIQIIv3+Q6MJNnLzxUA6EXsp4Qt3Qf3R1+EkI/RWOPbQsddpFNJBcBNOscCUFSZV3+ZK9E2RyHbPaL+Da4aJKVpgD7X1TFudq4PClMUTkg8CuJh/kvy9wkpaWyYHbLGQqu1vQ+NQ+vlTAKf8U+1xhC1IkX6nA+g4TlRksZRltRhpkBPnFoaQQGjD9eYyT1V/Htrn8Y/VGbYPBVa0GcEYXG5pDCBPz91RBpYwDcyUg9DEPNI6zYfQY8jA8xqtFwPX79Y22MDXIKhBskK00geuzh7Npy5Rnh4fLqVKMlffvYx3kwp444EFWtQ5jxbRCym2Th6EldkOM8Kble1JvixQtVb4s+DpTuwHCTrXZhwMuJpmwgRx52zyIsGrBPF3MOmdlwl+l0TD8UEJXt0JM1XSF1AROyYwXKDZQ9Qt4sd9ZKSWWaLJMEJf4kkZWYgTEI/FhOWlfshQCt8Z9S9r4fq2ywoo=
|
||||||
|
# file: $TRAVIS_BUILD_DIR/solidity-develop-$ZIP_SUFFIX.zip
|
||||||
|
# skip_cleanup: true
|
||||||
|
# on:
|
||||||
|
# repo: ethereum/solidity
|
||||||
|
# branch: develop
|
||||||
|
|
||||||
|
# This is the deploy target for the Emscripten build, which publishes
|
||||||
|
# generated JS for particular Solidity commits into
|
||||||
|
# https://github.com/ethereum/solc-bin/tree/gh-pages/bin
|
||||||
|
# Disabled, but can be renamed when we have the "standalone" changes
|
||||||
|
# published back into the 'develop' branch.
|
||||||
|
#
|
||||||
|
deploy:
|
||||||
|
provider: script
|
||||||
|
script: scripts/travis-emscripten/publish_binary.sh
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
branch: develop
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.0.0)
|
cmake_minimum_required(VERSION 3.0.0)
|
||||||
|
|
||||||
set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/../webthree-helpers/cmake" CACHE PATH "The the path to the cmake directory")
|
set(ETH_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The the path to the cmake directory")
|
||||||
list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR})
|
list(APPEND CMAKE_MODULE_PATH ${ETH_CMAKE_DIR})
|
||||||
|
|
||||||
# Set cmake_policies
|
# Set cmake_policies
|
||||||
@ -26,6 +26,7 @@ include(EthUtils)
|
|||||||
include(EthOptions)
|
include(EthOptions)
|
||||||
configure_project(TESTS)
|
configure_project(TESTS)
|
||||||
|
|
||||||
|
add_subdirectory(libdevcore)
|
||||||
add_subdirectory(libevmasm)
|
add_subdirectory(libevmasm)
|
||||||
add_subdirectory(libsolidity)
|
add_subdirectory(libsolidity)
|
||||||
add_subdirectory(solc)
|
add_subdirectory(solc)
|
||||||
|
76
appveyor.yml
Normal file
76
appveyor.yml
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Appveyor configuration file for solidity.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# http://solidity.readthedocs.org
|
||||||
|
#
|
||||||
|
# TODO - Tests currently disabled, because Tests-over-IPC code is using UNIX
|
||||||
|
# sockets unconditionally at the time of writing.
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of cpp-ethereum.
|
||||||
|
#
|
||||||
|
# cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 cpp-ethereum contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
version: 0.3.5.{build}
|
||||||
|
skip_tags: true
|
||||||
|
os: Visual Studio 2015
|
||||||
|
configuration:
|
||||||
|
- RelWithDebInfo
|
||||||
|
cache: build
|
||||||
|
install:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- scripts/install_deps.bat
|
||||||
|
- set ETHEREUM_DEPS_PATH=%APPVEYOR_BUILD_FOLDER%\deps\install
|
||||||
|
before_build:
|
||||||
|
- if not exist build mkdir build
|
||||||
|
- cd build
|
||||||
|
- cmake -G "Visual Studio 14 2015 Win64" .. -DTESTS=Off
|
||||||
|
build_script:
|
||||||
|
- msbuild solidity.sln /p:Configuration=%CONFIGURATION% /m:%NUMBER_OF_PROCESSORS% /v:minimal
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%
|
||||||
|
- scripts\release.bat %CONFIGURATION%
|
||||||
|
|
||||||
|
#test_script:
|
||||||
|
# - cd %APPVEYOR_BUILD_FOLDER%\build\test\%CONFIGURATION%
|
||||||
|
# - copy "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x86\Microsoft.VC140.CRT\msvc*.dll" .
|
||||||
|
# - eth.exe --test -d %TMP%/test
|
||||||
|
# - soltest.exe --ipc /tmp/test/geth.ipc
|
||||||
|
# - pkill eth
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: solidity-develop-windows.zip
|
||||||
|
name: solidity-develop-windows-zip
|
||||||
|
|
||||||
|
# This is the deploy target for Windows
|
||||||
|
# which generates development ZIPs per commit. We are in agreement
|
||||||
|
# that this is probably noisy overkill, so will want to renable this
|
||||||
|
# functionality wrapped in some conditionals so that it only runs
|
||||||
|
# when building the 'release' branch.
|
||||||
|
#
|
||||||
|
#deploy:
|
||||||
|
# release: solidity-develop-v$(APPVEYOR_BUILD_VERSION)
|
||||||
|
# tag: develop-v$(APPVEYOR_BUILD_VERSION)
|
||||||
|
# description: 'Development build of solidity at commit $(APPVEYOR_REPO_COMMIT).\n\n$(APPVEYOR_REPO_COMMIT_MESSAGE)\n\nCommitted by $(APPVEYOR_REPO_COMMIT_AUTHOR), $(APPVEYOR_REPO_COMMIT_TIMESTAMP).'
|
||||||
|
# prerelease: true
|
||||||
|
# provider: GitHub
|
||||||
|
# auth_token:
|
||||||
|
# secure: yukM9mHUbzuZSS5WSBLKSW0yGJerJEqAXkFhDhSHBBcKJE7GAryjQsdO9Kxh3yRv
|
||||||
|
# artifact: solidity-develop-windows-zip
|
||||||
|
# on:
|
||||||
|
# branch: standalone_changes
|
161
cmake/CMakeParseArguments.cmake
Normal file
161
cmake/CMakeParseArguments.cmake
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#.rst:
|
||||||
|
# CMakeParseArguments
|
||||||
|
# -------------------
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords>
|
||||||
|
# <multi_value_keywords> args...)
|
||||||
|
#
|
||||||
|
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions
|
||||||
|
# for parsing the arguments given to that macro or function. It
|
||||||
|
# processes the arguments and defines a set of variables which hold the
|
||||||
|
# values of the respective options.
|
||||||
|
#
|
||||||
|
# The <options> argument contains all options for the respective macro,
|
||||||
|
# i.e. keywords which can be used when calling the macro without any
|
||||||
|
# value following, like e.g. the OPTIONAL keyword of the install()
|
||||||
|
# command.
|
||||||
|
#
|
||||||
|
# The <one_value_keywords> argument contains all keywords for this macro
|
||||||
|
# which are followed by one value, like e.g. DESTINATION keyword of the
|
||||||
|
# install() command.
|
||||||
|
#
|
||||||
|
# The <multi_value_keywords> argument contains all keywords for this
|
||||||
|
# macro which can be followed by more than one value, like e.g. the
|
||||||
|
# TARGETS or FILES keywords of the install() command.
|
||||||
|
#
|
||||||
|
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
|
||||||
|
# keywords listed in <options>, <one_value_keywords> and
|
||||||
|
# <multi_value_keywords> a variable composed of the given <prefix>
|
||||||
|
# followed by "_" and the name of the respective keyword. These
|
||||||
|
# variables will then hold the respective value from the argument list.
|
||||||
|
# For the <options> keywords this will be TRUE or FALSE.
|
||||||
|
#
|
||||||
|
# All remaining arguments are collected in a variable
|
||||||
|
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see
|
||||||
|
# whether your macro was called with unrecognized parameters.
|
||||||
|
#
|
||||||
|
# As an example here a my_install() macro, which takes similar arguments
|
||||||
|
# as the real install() command:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# function(MY_INSTALL)
|
||||||
|
# set(options OPTIONAL FAST)
|
||||||
|
# set(oneValueArgs DESTINATION RENAME)
|
||||||
|
# set(multiValueArgs TARGETS CONFIGURATIONS)
|
||||||
|
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
|
||||||
|
# "${multiValueArgs}" ${ARGN} )
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Assume my_install() has been called like this:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# After the cmake_parse_arguments() call the macro will have set the
|
||||||
|
# following variables:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# MY_INSTALL_OPTIONAL = TRUE
|
||||||
|
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
|
||||||
|
# MY_INSTALL_DESTINATION = "bin"
|
||||||
|
# MY_INSTALL_RENAME = "" (was not used)
|
||||||
|
# MY_INSTALL_TARGETS = "foo;bar"
|
||||||
|
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
|
||||||
|
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# You can then continue and process these variables.
|
||||||
|
#
|
||||||
|
# Keywords terminate lists of values, e.g. if directly after a
|
||||||
|
# one_value_keyword another recognized keyword follows, this is
|
||||||
|
# interpreted as the beginning of the new option. E.g.
|
||||||
|
# my_install(TARGETS foo DESTINATION OPTIONAL) would result in
|
||||||
|
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION
|
||||||
|
# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
|
||||||
|
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
|
||||||
|
|
||||||
|
|
||||||
|
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
|
||||||
|
# first set all result variables to empty/FALSE
|
||||||
|
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
|
||||||
|
set(${prefix}_${arg_name})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
foreach(option ${_optionNames})
|
||||||
|
set(${prefix}_${option} FALSE)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(${prefix}_UNPARSED_ARGUMENTS)
|
||||||
|
|
||||||
|
set(insideValues FALSE)
|
||||||
|
set(currentArgName)
|
||||||
|
|
||||||
|
# now iterate over all arguments and fill the result variables
|
||||||
|
foreach(currentArg ${ARGN})
|
||||||
|
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||||
|
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||||
|
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
|
||||||
|
|
||||||
|
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
|
||||||
|
if(insideValues)
|
||||||
|
if("${insideValues}" STREQUAL "SINGLE")
|
||||||
|
set(${prefix}_${currentArgName} ${currentArg})
|
||||||
|
set(insideValues FALSE)
|
||||||
|
elseif("${insideValues}" STREQUAL "MULTI")
|
||||||
|
list(APPEND ${prefix}_${currentArgName} ${currentArg})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(NOT ${optionIndex} EQUAL -1)
|
||||||
|
set(${prefix}_${currentArg} TRUE)
|
||||||
|
set(insideValues FALSE)
|
||||||
|
elseif(NOT ${singleArgIndex} EQUAL -1)
|
||||||
|
set(currentArgName ${currentArg})
|
||||||
|
set(${prefix}_${currentArgName})
|
||||||
|
set(insideValues "SINGLE")
|
||||||
|
elseif(NOT ${multiArgIndex} EQUAL -1)
|
||||||
|
set(currentArgName ${currentArg})
|
||||||
|
set(${prefix}_${currentArgName})
|
||||||
|
set(insideValues "MULTI")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# propagate the result variables to the caller:
|
||||||
|
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
|
||||||
|
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
|
||||||
|
endforeach()
|
||||||
|
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endfunction()
|
45
cmake/EthBuildInfo.cmake
Normal file
45
cmake/EthBuildInfo.cmake
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
function(create_build_info NAME)
|
||||||
|
|
||||||
|
# Set build platform; to be written to BuildInfo.h
|
||||||
|
set(ETH_BUILD_OS "${CMAKE_SYSTEM_NAME}")
|
||||||
|
|
||||||
|
if (CMAKE_COMPILER_IS_MINGW)
|
||||||
|
set(ETH_BUILD_COMPILER "mingw")
|
||||||
|
elseif (CMAKE_COMPILER_IS_MSYS)
|
||||||
|
set(ETH_BUILD_COMPILER "msys")
|
||||||
|
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
set(ETH_BUILD_COMPILER "g++")
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
set(ETH_BUILD_COMPILER "msvc")
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set(ETH_BUILD_COMPILER "clang")
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||||
|
set(ETH_BUILD_COMPILER "appleclang")
|
||||||
|
else ()
|
||||||
|
set(ETH_BUILD_COMPILER "unknown")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(ETH_BUILD_PLATFORM "${ETH_BUILD_OS}/${ETH_BUILD_COMPILER}")
|
||||||
|
|
||||||
|
#cmake build type may be not speCified when using msvc
|
||||||
|
if (CMAKE_BUILD_TYPE)
|
||||||
|
set(_cmake_build_type ${CMAKE_BUILD_TYPE})
|
||||||
|
else()
|
||||||
|
set(_cmake_build_type "${CMAKE_CFG_INTDIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Generate header file containing useful build information
|
||||||
|
add_custom_target(${NAME}_BuildInfo.h ALL
|
||||||
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR="${PROJECT_SOURCE_DIR}" -DETH_BUILDINFO_IN="${ETH_CMAKE_DIR}/templates/BuildInfo.h.in" -DETH_DST_DIR="${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}" -DETH_CMAKE_DIR="${ETH_CMAKE_DIR}"
|
||||||
|
-DETH_BUILD_TYPE="${_cmake_build_type}"
|
||||||
|
-DETH_BUILD_OS="${ETH_BUILD_OS}"
|
||||||
|
-DETH_BUILD_COMPILER="${ETH_BUILD_COMPILER}"
|
||||||
|
-DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}"
|
||||||
|
-DETH_BUILD_NUMBER="${BUILD_NUMBER}"
|
||||||
|
-DETH_VERSION_SUFFIX="${VERSION_SUFFIX}"
|
||||||
|
-DPROJECT_VERSION="${PROJECT_VERSION}"
|
||||||
|
-P "${ETH_SCRIPTS_DIR}/buildinfo.cmake"
|
||||||
|
)
|
||||||
|
include_directories(BEFORE ${PROJECT_BINARY_DIR})
|
||||||
|
endfunction()
|
247
cmake/EthCompilerSettings.cmake
Normal file
247
cmake/EthCompilerSettings.cmake
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# EthCompilerSettings.cmake
|
||||||
|
#
|
||||||
|
# CMake file for cpp-ethereum project which specifies our compiler settings
|
||||||
|
# for each supported platform and build configuration.
|
||||||
|
#
|
||||||
|
# See http://www.ethdocs.org/en/latest/ethereum-clients/cpp-ethereum/.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014-2016 cpp-ethereum contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Clang seeks to be command-line compatible with GCC as much as possible, so
|
||||||
|
# most of our compiler settings are common between GCC and Clang.
|
||||||
|
#
|
||||||
|
# These settings then end up spanning all POSIX platforms (Linux, OS X, BSD, etc)
|
||||||
|
|
||||||
|
# Use ccache if available
|
||||||
|
find_program(CCACHE_FOUND ccache)
|
||||||
|
if(CCACHE_FOUND)
|
||||||
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||||
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||||
|
message("Using ccache")
|
||||||
|
endif(CCACHE_FOUND)
|
||||||
|
|
||||||
|
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
|
||||||
|
|
||||||
|
# Use ISO C++11 standard language.
|
||||||
|
set(CMAKE_CXX_FLAGS -std=c++11)
|
||||||
|
|
||||||
|
# Enables all the warnings about constructions that some users consider questionable,
|
||||||
|
# and that are easy to avoid. Also enable some extra warning flags that are not
|
||||||
|
# enabled by -Wall. Finally, treat at warnings-as-errors, which forces developers
|
||||||
|
# to fix warnings as they arise, so they don't accumulate "to be fixed later".
|
||||||
|
add_compile_options(-Wall)
|
||||||
|
add_compile_options(-Wextra)
|
||||||
|
add_compile_options(-Werror)
|
||||||
|
|
||||||
|
# Disable warnings about unknown pragmas (which is enabled by -Wall). I assume we have external
|
||||||
|
# dependencies (probably Boost) which have some of these. Whatever the case, we shouldn't be
|
||||||
|
# disabling these globally. Instead, we should pragma around just the problem #includes.
|
||||||
|
#
|
||||||
|
# TODO - Track down what breaks if we do NOT do this.
|
||||||
|
add_compile_options(-Wno-unknown-pragmas)
|
||||||
|
|
||||||
|
# To get the code building on FreeBSD and Arch Linux we seem to need the following
|
||||||
|
# warning suppression to work around some issues in Boost headers.
|
||||||
|
#
|
||||||
|
# See the following reports:
|
||||||
|
# https://github.com/ethereum/webthree-umbrella/issues/384
|
||||||
|
# https://github.com/ethereum/webthree-helpers/pull/170
|
||||||
|
#
|
||||||
|
# The issue manifest as warnings-as-errors like the following:
|
||||||
|
#
|
||||||
|
# /usr/local/include/boost/multiprecision/cpp_int.hpp:181:4: error:
|
||||||
|
# right operand of shift expression '(1u << 63u)' is >= than the precision of the left operand
|
||||||
|
#
|
||||||
|
# -fpermissive is a pretty nasty way to address this. It is described as follows:
|
||||||
|
#
|
||||||
|
# Downgrade some diagnostics about nonconformant code from errors to warnings.
|
||||||
|
# Thus, using -fpermissive will allow some nonconforming code to compile.
|
||||||
|
#
|
||||||
|
# NB: Have to use this form for the setting, so that it only applies to C++ builds.
|
||||||
|
# Applying -fpermissive to a C command-line (ie. secp256k1) gives a build error.
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
|
||||||
|
|
||||||
|
# Build everything as shared libraries (.so files)
|
||||||
|
add_definitions(-DSHAREDLIB)
|
||||||
|
|
||||||
|
# If supported for the target machine, emit position-independent code, suitable for dynamic
|
||||||
|
# linking and avoiding any limit on the size of the global offset table.
|
||||||
|
add_compile_options(-fPIC)
|
||||||
|
|
||||||
|
# Configuration-specific compiler settings.
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG")
|
||||||
|
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
||||||
|
|
||||||
|
# Additional GCC-specific compiler settings.
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||||
|
|
||||||
|
# Check that we've got GCC 4.7 or newer.
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
|
||||||
|
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
|
||||||
|
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Strong stack protection was only added in GCC 4.9.
|
||||||
|
# Use it if we have the option to do so.
|
||||||
|
# See https://lwn.net/Articles/584225/
|
||||||
|
if (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9)
|
||||||
|
add_compile_options(-fstack-protector-strong)
|
||||||
|
add_compile_options(-fstack-protector)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Additional Clang-specific compiler settings.
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||||
|
|
||||||
|
add_compile_options(-fstack-protector)
|
||||||
|
|
||||||
|
# Enable strong stack protection only on Mac and only for OS X Yosemite
|
||||||
|
# or newer (AppleClang 7.0+). We should be able to re-enable this setting
|
||||||
|
# on non-Apple Clang as well, if we can work out what expression to use for
|
||||||
|
# the version detection.
|
||||||
|
|
||||||
|
# The fact that the version-reporting for AppleClang loses the original
|
||||||
|
# Clang versioning is rather annoying. Ideally we could just have
|
||||||
|
# a single cross-platform "if version >= 3.4.1" check.
|
||||||
|
#
|
||||||
|
# There is debug text in the else clause below, to help us work out what
|
||||||
|
# such an expression should be, if we can get this running on a Trusty box
|
||||||
|
# with Clang. Greg Colvin previously replicated the issue there too.
|
||||||
|
#
|
||||||
|
# See https://github.com/ethereum/webthree-umbrella/issues/594
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||||
|
add_compile_options(-fstack-protector-strong)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# A couple of extra warnings suppressions which we seemingly
|
||||||
|
# need when building with Clang.
|
||||||
|
#
|
||||||
|
# TODO - Nail down exactly where these warnings are manifesting and
|
||||||
|
# try to suppress them in a more localized way. Notes in this file
|
||||||
|
# indicate that the first is needed for sepc256k1 and that the
|
||||||
|
# second is needed for the (clog, cwarn) macros. These will need
|
||||||
|
# testing on at least OS X and Ubuntu.
|
||||||
|
add_compile_options(-Wno-unused-function)
|
||||||
|
add_compile_options(-Wno-dangling-else)
|
||||||
|
|
||||||
|
# Some Linux-specific Clang settings. We don't want these for OS X.
|
||||||
|
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||||
|
|
||||||
|
# TODO - Is this even necessary? Why?
|
||||||
|
# See http://stackoverflow.com/questions/19774778/when-is-it-necessary-to-use-use-the-flag-stdlib-libstdc.
|
||||||
|
add_compile_options(-stdlib=libstdc++)
|
||||||
|
|
||||||
|
# Tell Boost that we're using Clang's libc++. Not sure exactly why we need to do.
|
||||||
|
add_definitions(-DBOOST_ASIO_HAS_CLANG_LIBCXX)
|
||||||
|
|
||||||
|
# Use fancy colors in the compiler diagnostics
|
||||||
|
add_compile_options(-fcolor-diagnostics)
|
||||||
|
|
||||||
|
# See "How to silence unused command line argument error with clang without disabling it?"
|
||||||
|
# When using -Werror with clang, it transforms "warning: argument unused during compilation" messages
|
||||||
|
# into errors, which makes sense.
|
||||||
|
# http://stackoverflow.com/questions/21617158/how-to-silence-unused-command-line-argument-error-with-clang-without-disabling-i
|
||||||
|
add_compile_options(-Qunused-arguments)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (EMSCRIPTEN)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --memory-init-file 0 -O3 -s LINKABLE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s NO_EXIT_RUNTIME=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_DYNAMIC_EXECUTION=1")
|
||||||
|
add_definitions(-DETH_EMSCRIPTEN=1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# The major alternative compiler to GCC/Clang is Microsoft's Visual C++ compiler, only available on Windows.
|
||||||
|
elseif (DEFINED MSVC)
|
||||||
|
|
||||||
|
add_compile_options(/MP) # enable parallel compilation
|
||||||
|
add_compile_options(/EHsc) # specify Exception Handling Model in msvc
|
||||||
|
add_compile_options(/WX) # enable warnings-as-errors
|
||||||
|
add_compile_options(/wd4068) # disable unknown pragma warning (4068)
|
||||||
|
add_compile_options(/wd4996) # disable unsafe function warning (4996)
|
||||||
|
add_compile_options(/wd4503) # disable decorated name length exceeded, name was truncated (4503)
|
||||||
|
add_compile_options(/wd4267) # disable conversion from 'size_t' to 'type', possible loss of data (4267)
|
||||||
|
add_compile_options(/wd4180) # disable qualifier applied to function type has no meaning; ignored (4180)
|
||||||
|
add_compile_options(/wd4290) # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (4290)
|
||||||
|
add_compile_options(/wd4244) # disable conversion from 'type1' to 'type2', possible loss of data (4244)
|
||||||
|
add_compile_options(/wd4800) # disable forcing value to bool 'true' or 'false' (performance warning) (4800)
|
||||||
|
add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement
|
||||||
|
add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions
|
||||||
|
add_compile_options(-DMINIUPNP_STATICLIB) # define miniupnp static library
|
||||||
|
|
||||||
|
# Always use Release variant of C++ runtime.
|
||||||
|
# We don't want to provide Debug variants of all dependencies. Some default
|
||||||
|
# flags set by CMake must be tweaked.
|
||||||
|
string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||||
|
string(REPLACE "/D_DEBUG" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||||
|
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||||
|
string(REPLACE "/MDd" "/MD" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
|
||||||
|
string(REPLACE "/D_DEBUG" "" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
|
||||||
|
string(REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
|
||||||
|
set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS OFF)
|
||||||
|
|
||||||
|
# disable empty object file warning
|
||||||
|
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
|
||||||
|
# warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification
|
||||||
|
# warning LNK4099: pdb was not found with lib
|
||||||
|
# stack size 16MB
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216")
|
||||||
|
|
||||||
|
# windows likes static
|
||||||
|
if (NOT ETH_STATIC)
|
||||||
|
message("Forcing static linkage for MSVC.")
|
||||||
|
set(ETH_STATIC 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# If you don't have GCC, Clang or VC++ then you are on your own. Good luck!
|
||||||
|
else ()
|
||||||
|
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (SANITIZE)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=${SANITIZE}")
|
||||||
|
if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/sanitizer-blacklist.txt")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
|
||||||
|
set(CMAKE_CXX_FLAGS "-g ${CMAKE_CXX_FLAGS}")
|
||||||
|
set(CMAKE_C_FLAGS "-g ${CMAKE_C_FLAGS}")
|
||||||
|
add_definitions(-DETH_PROFILING_GPERF)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
|
||||||
|
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lprofiler")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (PROFILING AND (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")))
|
||||||
|
set(CMAKE_CXX_FLAGS "-g --coverage ${CMAKE_CXX_FLAGS}")
|
||||||
|
set(CMAKE_C_FLAGS "-g --coverage ${CMAKE_C_FLAGS}")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "--coverage ${CMAKE_SHARED_LINKER_FLAGS} -lprofiler")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "--coverage ${CMAKE_EXE_LINKER_FLAGS} -lprofiler")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
|
||||||
|
option(USE_LD_GOLD "Use GNU gold linker" ON)
|
||||||
|
if (USE_LD_GOLD)
|
||||||
|
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
|
if ("${LD_VERSION}" MATCHES "GNU gold")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(ETH_STATIC)
|
||||||
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
|
else()
|
||||||
|
set(BUILD_SHARED_LIBS ON)
|
||||||
|
endif(ETH_STATIC)
|
136
cmake/EthDependencies.cmake
Normal file
136
cmake/EthDependencies.cmake
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# all dependencies that are not directly included in the cpp-ethereum distribution are defined here
|
||||||
|
# for this to work, download the dependency via the cmake script in extdep or install them manually!
|
||||||
|
|
||||||
|
function(eth_show_dependency DEP NAME)
|
||||||
|
get_property(DISPLAYED GLOBAL PROPERTY ETH_${DEP}_DISPLAYED)
|
||||||
|
if (NOT DISPLAYED)
|
||||||
|
set_property(GLOBAL PROPERTY ETH_${DEP}_DISPLAYED TRUE)
|
||||||
|
message(STATUS "${NAME} headers: ${${DEP}_INCLUDE_DIRS}")
|
||||||
|
message(STATUS "${NAME} lib : ${${DEP}_LIBRARIES}")
|
||||||
|
if (NOT("${${DEP}_DLLS}" STREQUAL ""))
|
||||||
|
message(STATUS "${NAME} dll : ${${DEP}_DLLS}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if (DEFINED MSVC)
|
||||||
|
# by defining CMAKE_PREFIX_PATH variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ...
|
||||||
|
# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0)
|
||||||
|
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_LIST_DIR}/../extdep/install/windows/x64")
|
||||||
|
else()
|
||||||
|
get_filename_component(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps/install" ABSOLUTE)
|
||||||
|
set(ETH_DEPENDENCY_INSTALL_DIR
|
||||||
|
"${DEPS_DIR}/x64" # Old location for deps.
|
||||||
|
"${DEPS_DIR}/win64" # New location for deps.
|
||||||
|
"${DEPS_DIR}/win64/Release/share" # LLVM shared cmake files.
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR} ${CMAKE_PREFIX_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# custom cmake scripts
|
||||||
|
set(ETH_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
set(ETH_SCRIPTS_DIR ${ETH_CMAKE_DIR}/scripts)
|
||||||
|
|
||||||
|
find_program(CTEST_COMMAND ctest)
|
||||||
|
|
||||||
|
#message(STATUS "CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}")
|
||||||
|
#message(STATUS "CMake Helper Path: ${ETH_CMAKE_DIR}")
|
||||||
|
#message(STATUS "CMake Script Path: ${ETH_SCRIPTS_DIR}")
|
||||||
|
#message(STATUS "ctest path: ${CTEST_COMMAND}")
|
||||||
|
|
||||||
|
## use multithreaded boost libraries, with -mt suffix
|
||||||
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
|
||||||
|
# use static boost libraries *.lib
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
|
||||||
|
elseif (APPLE)
|
||||||
|
|
||||||
|
# use static boost libraries *.a
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
|
||||||
|
elseif (UNIX)
|
||||||
|
# use dynamic boost libraries *.dll
|
||||||
|
set(Boost_USE_STATIC_LIBS OFF)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(STATIC_LINKING FALSE CACHE BOOL "Build static binaries")
|
||||||
|
|
||||||
|
if (STATIC_LINKING)
|
||||||
|
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
set(Boost_USE_STATIC_RUNTIME ON)
|
||||||
|
|
||||||
|
set(OpenSSL_USE_STATIC_LIBS ON)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# TODO - Why would we need .a on Windows? Maybe some Cygwin-ism.
|
||||||
|
# When I work through Windows static linkage, I will remove this,
|
||||||
|
# if that is possible.
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
|
elseif (APPLE)
|
||||||
|
# At the time of writing, we are still only PARTIALLY statically linked
|
||||||
|
# on OS X, with a mixture of statically linked external libraries where
|
||||||
|
# those are available, and dynamically linked where that is the only
|
||||||
|
# option we have. Ultimately, the aim would be for everything except
|
||||||
|
# the runtime libraries to be statically linked.
|
||||||
|
#
|
||||||
|
# Still TODO:
|
||||||
|
# - jsoncpp
|
||||||
|
# - json-rpc-cpp
|
||||||
|
# - leveldb (which pulls in snappy, for the dylib at ;east)
|
||||||
|
# - miniupnp
|
||||||
|
# - gmp
|
||||||
|
#
|
||||||
|
# Two further libraries (curl and zlib) ship as dylibs with the platform
|
||||||
|
# but again we could build from source and statically link these too.
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .dylib)
|
||||||
|
else()
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ETH_STATIC ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(Boost 1.54.0 QUIET REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework program_options random)
|
||||||
|
|
||||||
|
eth_show_dependency(Boost boost)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
link_directories(/usr/local/lib)
|
||||||
|
include_directories(/usr/local/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(BEFORE "${PROJECT_BINARY_DIR}/include")
|
||||||
|
|
||||||
|
function(eth_use TARGET REQUIRED)
|
||||||
|
if (NOT TARGET ${TARGET})
|
||||||
|
message(FATAL_ERROR "eth_use called for non existing target ${TARGET}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET ${PROJECT_NAME}_BuildInfo.h)
|
||||||
|
add_dependencies(${TARGET} ${PROJECT_NAME}_BuildInfo.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(MODULE ${ARGN})
|
||||||
|
string(REPLACE "::" ";" MODULE_PARTS ${MODULE})
|
||||||
|
list(GET MODULE_PARTS 0 MODULE_MAIN)
|
||||||
|
list(LENGTH MODULE_PARTS MODULE_LENGTH)
|
||||||
|
if (MODULE_LENGTH GREATER 1)
|
||||||
|
list(GET MODULE_PARTS 1 MODULE_SUB)
|
||||||
|
endif()
|
||||||
|
# TODO: check if file exists if not, throws FATAL_ERROR with detailed description
|
||||||
|
get_target_property(TARGET_APPLIED ${TARGET} TARGET_APPLIED_${MODULE_MAIN}_${MODULE_SUB})
|
||||||
|
if (NOT TARGET_APPLIED)
|
||||||
|
include(Use${MODULE_MAIN})
|
||||||
|
set_target_properties(${TARGET} PROPERTIES TARGET_APPLIED_${MODULE_MAIN}_${MODULE_SUB} TRUE)
|
||||||
|
eth_apply(${TARGET} ${REQUIRED} ${MODULE_SUB})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
143
cmake/EthExecutableHelper.cmake
Normal file
143
cmake/EthExecutableHelper.cmake
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#
|
||||||
|
# this function requires the following variables to be specified:
|
||||||
|
# ETH_VERSION
|
||||||
|
# PROJECT_NAME
|
||||||
|
# PROJECT_VERSION
|
||||||
|
# PROJECT_COPYRIGHT_YEAR
|
||||||
|
# PROJECT_VENDOR
|
||||||
|
# PROJECT_DOMAIN_SECOND
|
||||||
|
# PROJECT_DOMAIN_FIRST
|
||||||
|
# SRC_LIST
|
||||||
|
# HEADERS
|
||||||
|
#
|
||||||
|
# params:
|
||||||
|
# ICON
|
||||||
|
#
|
||||||
|
|
||||||
|
macro(eth_add_executable EXECUTABLE)
|
||||||
|
set (extra_macro_args ${ARGN})
|
||||||
|
set (options)
|
||||||
|
set (one_value_args ICON)
|
||||||
|
set (multi_value_args UI_RESOURCES WIN_RESOURCES)
|
||||||
|
cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
|
||||||
|
add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${ETH_ADD_EXECUTABLE_UI_RESOURCES})
|
||||||
|
set(PROJECT_VERSION "${ETH_VERSION}")
|
||||||
|
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||||
|
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||||
|
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||||
|
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
|
||||||
|
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}")
|
||||||
|
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}")
|
||||||
|
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE})
|
||||||
|
set(MACOSX_BUNDLE_ICON_FILE ${ETH_ADD_EXECUTABLE_ICON})
|
||||||
|
set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
|
||||||
|
set_source_files_properties(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
|
||||||
|
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${MACOSX_BUNDLE_ICON_FILE}.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||||
|
|
||||||
|
else ()
|
||||||
|
add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${ETH_ADD_EXECUTABLE_WIN_RESOURCES} ${SRC_LIST} ${HEADERS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(eth_simple_add_executable EXECUTABLE)
|
||||||
|
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
|
||||||
|
|
||||||
|
# Apple does not support statically linked binaries on OS X. That means
|
||||||
|
# that we can only statically link against our external libraries, but
|
||||||
|
# we cannot statically link against the C++ runtime libraries and other
|
||||||
|
# platform libraries (as is possible on Windows and Alpine Linux) to produce
|
||||||
|
# an entirely transportable binary.
|
||||||
|
#
|
||||||
|
# See https://developer.apple.com/library/mac/qa/qa1118/_index.html for more info.
|
||||||
|
#
|
||||||
|
# GLIBC also appears not to support static linkage too, which probably means that
|
||||||
|
# Debian and Ubuntu will only be able to do partially-statically linked
|
||||||
|
# executables too, just like OS X.
|
||||||
|
#
|
||||||
|
# For OS X, at the time of writing, we are left with the following dynamically
|
||||||
|
# linked dependencies, of which curl and libz might still be fixable:
|
||||||
|
#
|
||||||
|
# /usr/lib/libc++.1.dylib
|
||||||
|
# /usr/lib/libSystem.B.dylib
|
||||||
|
# /usr/lib/libcurl.4.dylib
|
||||||
|
# /usr/lib/libz.1.dylib
|
||||||
|
#
|
||||||
|
if (STATIC_LINKING AND NOT APPLE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-static ${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
set_target_properties(${EXECUTABLE} PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||||
|
set_target_properties(${EXECUTABLE} PROPERTIES LINK_SEARCH_END_STATIC 1)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(eth_copy_dll EXECUTABLE DLL)
|
||||||
|
# dlls must be unsubstitud list variable (without ${}) in format
|
||||||
|
# optimized;path_to_dll.dll;debug;path_to_dlld.dll
|
||||||
|
if(DEFINED MSVC)
|
||||||
|
list(GET ${DLL} 1 DLL_RELEASE)
|
||||||
|
list(GET ${DLL} 3 DLL_DEBUG)
|
||||||
|
add_custom_command(TARGET ${EXECUTABLE}
|
||||||
|
PRE_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} ARGS
|
||||||
|
-DDLL_RELEASE="${DLL_RELEASE}"
|
||||||
|
-DDLL_DEBUG="${DLL_DEBUG}"
|
||||||
|
-DCONF="$<CONFIGURATION>"
|
||||||
|
-DDESTINATION="${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
|
||||||
|
-P "${ETH_SCRIPTS_DIR}/copydlls.cmake"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(eth_copy_dlls EXECUTABLE)
|
||||||
|
foreach(dll ${ARGN})
|
||||||
|
eth_copy_dll(${EXECUTABLE} ${dll})
|
||||||
|
endforeach(dll)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
macro(eth_install_executable EXECUTABLE)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
|
||||||
|
# TODO - Why is this different than the branch Linux below, which has the RUNTIME keyword too?
|
||||||
|
install(TARGETS ${EXECUTABLE} DESTINATION bin)
|
||||||
|
|
||||||
|
elseif (DEFINED MSVC)
|
||||||
|
|
||||||
|
set(COMPONENT ${EXECUTABLE})
|
||||||
|
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Debug/"
|
||||||
|
DESTINATION .
|
||||||
|
CONFIGURATIONS Debug
|
||||||
|
COMPONENT ${COMPONENT}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Release/"
|
||||||
|
DESTINATION .
|
||||||
|
CONFIGURATIONS Release
|
||||||
|
COMPONENT ${COMPONENT}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/"
|
||||||
|
DESTINATION .
|
||||||
|
CONFIGURATIONS RelWithDebInfo
|
||||||
|
COMPONENT ${COMPONENT}
|
||||||
|
)
|
||||||
|
|
||||||
|
else()
|
||||||
|
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro (eth_name KEY VALUE)
|
||||||
|
if (NOT (APPLE OR WIN32))
|
||||||
|
string(TOLOWER ${VALUE} LVALUE )
|
||||||
|
set(${KEY} ${LVALUE})
|
||||||
|
else()
|
||||||
|
set(${KEY} ${VALUE})
|
||||||
|
endif()
|
||||||
|
endmacro()
|
40
cmake/EthOptions.cmake
Normal file
40
cmake/EthOptions.cmake
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
macro(configure_project)
|
||||||
|
set(NAME ${PROJECT_NAME})
|
||||||
|
|
||||||
|
# features
|
||||||
|
eth_default_option(PROFILING OFF)
|
||||||
|
|
||||||
|
# components
|
||||||
|
eth_default_option(TESTS ON)
|
||||||
|
eth_default_option(TOOLS ON)
|
||||||
|
|
||||||
|
# Define a matching property name of each of the "features".
|
||||||
|
foreach(FEATURE ${ARGN})
|
||||||
|
set(SUPPORT_${FEATURE} TRUE)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
include(EthBuildInfo)
|
||||||
|
create_build_info(${NAME})
|
||||||
|
print_config(${NAME})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(print_config NAME)
|
||||||
|
message("")
|
||||||
|
message("------------------------------------------------------------------------")
|
||||||
|
message("-- Configuring ${NAME}")
|
||||||
|
message("------------------------------------------------------------------------")
|
||||||
|
message("-- CMake Version ${CMAKE_VERSION}")
|
||||||
|
message("-- CMAKE_BUILD_TYPE Build type ${CMAKE_BUILD_TYPE}")
|
||||||
|
message("-- TARGET_PLATFORM Target platform ${CMAKE_SYSTEM_NAME}")
|
||||||
|
message("--------------------------------------------------------------- features")
|
||||||
|
message("-- PROFILING Profiling support ${PROFILING}")
|
||||||
|
message("------------------------------------------------------------- components")
|
||||||
|
if (SUPPORT_TESTS)
|
||||||
|
message("-- TESTS Build tests ${TESTS}")
|
||||||
|
endif()
|
||||||
|
if (SUPPORT_TOOLS)
|
||||||
|
message("-- TOOLS Build tools ${TOOLS}")
|
||||||
|
endif()
|
||||||
|
message("------------------------------------------------------------------------")
|
||||||
|
message("")
|
||||||
|
endmacro()
|
35
cmake/EthPolicy.cmake
Normal file
35
cmake/EthPolicy.cmake
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# it must be a macro cause policies have scopes
|
||||||
|
# http://www.cmake.org/cmake/help/v3.0/command/cmake_policy.html
|
||||||
|
macro (eth_policy)
|
||||||
|
# link_directories() treats paths relative to the source dir.
|
||||||
|
cmake_policy(SET CMP0015 NEW)
|
||||||
|
|
||||||
|
# let cmake autolink dependencies on windows
|
||||||
|
cmake_policy(SET CMP0020 NEW)
|
||||||
|
|
||||||
|
# CMake 2.8.12 and lower allowed the use of targets and files with double
|
||||||
|
# colons in target_link_libraries,
|
||||||
|
cmake_policy(SET CMP0028 OLD)
|
||||||
|
|
||||||
|
if (${CMAKE_VERSION} VERSION_GREATER 3.0)
|
||||||
|
|
||||||
|
# fix MACOSX_RPATH
|
||||||
|
cmake_policy(SET CMP0042 OLD)
|
||||||
|
|
||||||
|
# ignore COMPILE_DEFINITIONS_<Config> properties
|
||||||
|
cmake_policy(SET CMP0043 OLD)
|
||||||
|
|
||||||
|
# allow VERSION argument in project()
|
||||||
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${CMAKE_VERSION} VERSION_GREATER 3.1)
|
||||||
|
|
||||||
|
# do not interpret if() arguments as variables!
|
||||||
|
cmake_policy(SET CMP0054 NEW)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endmacro()
|
||||||
|
|
114
cmake/EthUtils.cmake
Normal file
114
cmake/EthUtils.cmake
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#
|
||||||
|
# renames the file if it is different from its destination
|
||||||
|
include(CMakeParseArguments)
|
||||||
|
#
|
||||||
|
macro(replace_if_different SOURCE DST)
|
||||||
|
set(extra_macro_args ${ARGN})
|
||||||
|
set(options CREATE)
|
||||||
|
set(one_value_args)
|
||||||
|
set(multi_value_args)
|
||||||
|
cmake_parse_arguments(REPLACE_IF_DIFFERENT "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
|
||||||
|
|
||||||
|
if (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS "${DST}")))
|
||||||
|
file(WRITE "${DST}" "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${SOURCE}" "${DST}" RESULT_VARIABLE DIFFERENT OUTPUT_QUIET ERROR_QUIET)
|
||||||
|
|
||||||
|
if (DIFFERENT)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${SOURCE}" "${DST}")
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${SOURCE}")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(eth_add_test NAME)
|
||||||
|
|
||||||
|
# parse arguments here
|
||||||
|
set(commands)
|
||||||
|
set(current_command "")
|
||||||
|
foreach (arg ${ARGN})
|
||||||
|
if (arg STREQUAL "ARGS")
|
||||||
|
if (current_command)
|
||||||
|
list(APPEND commands ${current_command})
|
||||||
|
endif()
|
||||||
|
set(current_command "")
|
||||||
|
else ()
|
||||||
|
set(current_command "${current_command} ${arg}")
|
||||||
|
endif()
|
||||||
|
endforeach(arg)
|
||||||
|
list(APPEND commands ${current_command})
|
||||||
|
|
||||||
|
message(STATUS "test: ${NAME} | ${commands}")
|
||||||
|
|
||||||
|
# create tests
|
||||||
|
set(index 0)
|
||||||
|
list(LENGTH commands count)
|
||||||
|
while (index LESS count)
|
||||||
|
list(GET commands ${index} test_arguments)
|
||||||
|
|
||||||
|
set(run_test "--run_test=${NAME}")
|
||||||
|
add_test(NAME "${NAME}.${index}" COMMAND testeth ${run_test} ${test_arguments})
|
||||||
|
|
||||||
|
math(EXPR index "${index} + 1")
|
||||||
|
endwhile(index LESS count)
|
||||||
|
|
||||||
|
# add target to run them
|
||||||
|
add_custom_target("test.${NAME}"
|
||||||
|
DEPENDS testeth
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DETH_TEST_NAME="${NAME}" -DCTEST_COMMAND="${CTEST_COMMAND}" -P "${ETH_SCRIPTS_DIR}/runtest.cmake"
|
||||||
|
)
|
||||||
|
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Creates C resources file from files
|
||||||
|
function(eth_add_resources RESOURCE_FILE OUT_FILE ETH_RES_DIR)
|
||||||
|
include("${RESOURCE_FILE}")
|
||||||
|
set(OUTPUT "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}.hpp")
|
||||||
|
#message(FATAL_ERROR "res:! ${ETH_RESOURCE_LOCATION}")
|
||||||
|
include_directories("${ETH_RESOURCE_LOCATION}")
|
||||||
|
set(${OUT_FILE} "${OUTPUT}" PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(filenames "${RESOURCE_FILE}")
|
||||||
|
list(APPEND filenames "${ETH_SCRIPTS_DIR}/resources.cmake")
|
||||||
|
foreach(resource ${ETH_RESOURCES})
|
||||||
|
list(APPEND filenames "${${resource}}")
|
||||||
|
endforeach(resource)
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT ${OUTPUT}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -DETH_RES_DIR="${ETH_RES_DIR}" -P "${ETH_SCRIPTS_DIR}/resources.cmake"
|
||||||
|
DEPENDS ${filenames}
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
macro(eth_default_option O DEF)
|
||||||
|
if (DEFINED ${O})
|
||||||
|
if (${${O}})
|
||||||
|
set(${O} ON)
|
||||||
|
else ()
|
||||||
|
set(${O} OFF)
|
||||||
|
endif()
|
||||||
|
else ()
|
||||||
|
set(${O} ${DEF})
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# In Windows split repositories build we need to be checking whether or not
|
||||||
|
# Debug/Release or both versions were built for the config phase to run smoothly
|
||||||
|
macro(eth_check_library_link L)
|
||||||
|
if (${${L}_LIBRARY} AND ${${L}_LIBRARY} EQUAL "${L}_LIBRARY-NOTFOUND")
|
||||||
|
unset(${${L}_LIBRARY})
|
||||||
|
endif()
|
||||||
|
if (${${L}_LIBRARY_DEBUG} AND ${${L}_LIBRARY_DEBUG} EQUAL "${L}_LIBRARY_DEBUG-NOTFOUND")
|
||||||
|
unset(${${L}_LIBRARY_DEBUG})
|
||||||
|
endif()
|
||||||
|
if (${${L}_LIBRARY} AND ${${L}_LIBRARY_DEBUG})
|
||||||
|
set(${L}_LIBRARIES optimized ${${L}_LIBRARY} debug ${${L}_LIBRARY_DEBUG})
|
||||||
|
elseif (${${L}_LIBRARY})
|
||||||
|
set(${L}_LIBRARIES ${${L}_LIBRARY})
|
||||||
|
elseif (${${L}_LIBRARY_DEBUG})
|
||||||
|
set(${L}_LIBRARIES ${${L}_LIBRARY_DEBUG})
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
50
cmake/FindJsoncpp.cmake
Normal file
50
cmake/FindJsoncpp.cmake
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Find jsoncpp
|
||||||
|
#
|
||||||
|
# Find the jsoncpp includes and library
|
||||||
|
#
|
||||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH
|
||||||
|
#
|
||||||
|
# This module defines
|
||||||
|
# JSONCPP_INCLUDE_DIRS, where to find header, etc.
|
||||||
|
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
|
||||||
|
# JSONCPP_FOUND, If false, do not try to use jsoncpp.
|
||||||
|
|
||||||
|
# only look in default directories
|
||||||
|
find_path(
|
||||||
|
JSONCPP_INCLUDE_DIR
|
||||||
|
NAMES json/json.h
|
||||||
|
PATH_SUFFIXES jsoncpp
|
||||||
|
DOC "jsoncpp include dir"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(
|
||||||
|
JSONCPP_LIBRARY
|
||||||
|
NAMES jsoncpp
|
||||||
|
DOC "jsoncpp library"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
|
||||||
|
set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
|
||||||
|
|
||||||
|
# debug library on windows
|
||||||
|
# same naming convention as in qt (appending debug library with d)
|
||||||
|
# boost is using the same "hack" as us with "optimized" and "debug"
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
|
||||||
|
find_library(
|
||||||
|
JSONCPP_LIBRARY_DEBUG
|
||||||
|
NAMES jsoncppd
|
||||||
|
DOC "jsoncpp debug library"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(JSONCPP_LIBRARIES optimized ${JSONCPP_LIBRARIES} debug ${JSONCPP_LIBRARY_DEBUG})
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set JSONCPP_FOUND to TRUE
|
||||||
|
# if all listed variables are TRUE, hide their existence from configuration view
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(jsoncpp DEFAULT_MSG
|
||||||
|
JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
|
||||||
|
mark_as_advanced (JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY)
|
||||||
|
|
382
cmake/FindPackageHandleStandardArgs.cmake
Normal file
382
cmake/FindPackageHandleStandardArgs.cmake
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
#.rst:
|
||||||
|
# FindPackageHandleStandardArgs
|
||||||
|
# -----------------------------
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name> ... )
|
||||||
|
#
|
||||||
|
# This function is intended to be used in FindXXX.cmake modules files.
|
||||||
|
# It handles the REQUIRED, QUIET and version-related arguments to
|
||||||
|
# find_package(). It also sets the <packagename>_FOUND variable. The
|
||||||
|
# package is considered found if all variables <var1>... listed contain
|
||||||
|
# valid results, e.g. valid filepaths.
|
||||||
|
#
|
||||||
|
# There are two modes of this function. The first argument in both
|
||||||
|
# modes is the name of the Find-module where it is called (in original
|
||||||
|
# casing).
|
||||||
|
#
|
||||||
|
# The first simple mode looks like this:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<name>
|
||||||
|
# (DEFAULT_MSG|"Custom failure message") <var1>...<varN> )
|
||||||
|
#
|
||||||
|
# If the variables <var1> to <varN> are all valid, then
|
||||||
|
# <UPPERCASED_NAME>_FOUND will be set to TRUE. If DEFAULT_MSG is given
|
||||||
|
# as second argument, then the function will generate itself useful
|
||||||
|
# success and error messages. You can also supply a custom error
|
||||||
|
# message for the failure case. This is not recommended.
|
||||||
|
#
|
||||||
|
# The second mode is more powerful and also supports version checking:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME
|
||||||
|
# [FOUND_VAR <resultVar>]
|
||||||
|
# [REQUIRED_VARS <var1>...<varN>]
|
||||||
|
# [VERSION_VAR <versionvar>]
|
||||||
|
# [HANDLE_COMPONENTS]
|
||||||
|
# [CONFIG_MODE]
|
||||||
|
# [FAIL_MESSAGE "Custom failure message"] )
|
||||||
|
#
|
||||||
|
# In this mode, the name of the result-variable can be set either to
|
||||||
|
# either <UPPERCASED_NAME>_FOUND or <OriginalCase_Name>_FOUND using the
|
||||||
|
# FOUND_VAR option. Other names for the result-variable are not
|
||||||
|
# allowed. So for a Find-module named FindFooBar.cmake, the two
|
||||||
|
# possible names are FooBar_FOUND and FOOBAR_FOUND. It is recommended
|
||||||
|
# to use the original case version. If the FOUND_VAR option is not
|
||||||
|
# used, the default is <UPPERCASED_NAME>_FOUND.
|
||||||
|
#
|
||||||
|
# As in the simple mode, if <var1> through <varN> are all valid,
|
||||||
|
# <packagename>_FOUND will be set to TRUE. After REQUIRED_VARS the
|
||||||
|
# variables which are required for this package are listed. Following
|
||||||
|
# VERSION_VAR the name of the variable can be specified which holds the
|
||||||
|
# version of the package which has been found. If this is done, this
|
||||||
|
# version will be checked against the (potentially) specified required
|
||||||
|
# version used in the find_package() call. The EXACT keyword is also
|
||||||
|
# handled. The default messages include information about the required
|
||||||
|
# version and the version which has been actually found, both if the
|
||||||
|
# version is ok or not. If the package supports components, use the
|
||||||
|
# HANDLE_COMPONENTS option to enable handling them. In this case,
|
||||||
|
# find_package_handle_standard_args() will report which components have
|
||||||
|
# been found and which are missing, and the <packagename>_FOUND variable
|
||||||
|
# will be set to FALSE if any of the required components (i.e. not the
|
||||||
|
# ones listed after OPTIONAL_COMPONENTS) are missing. Use the option
|
||||||
|
# CONFIG_MODE if your FindXXX.cmake module is a wrapper for a
|
||||||
|
# find_package(... NO_MODULE) call. In this case VERSION_VAR will be
|
||||||
|
# set to <NAME>_VERSION and the macro will automatically check whether
|
||||||
|
# the Config module was found. Via FAIL_MESSAGE a custom failure
|
||||||
|
# message can be specified, if this is not used, the default message
|
||||||
|
# will be displayed.
|
||||||
|
#
|
||||||
|
# Example for mode 1:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# find_package_handle_standard_args(LibXml2 DEFAULT_MSG
|
||||||
|
# LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and
|
||||||
|
# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to
|
||||||
|
# TRUE. If it is not found and REQUIRED was used, it fails with
|
||||||
|
# FATAL_ERROR, independent whether QUIET was used or not. If it is
|
||||||
|
# found, success will be reported, including the content of <var1>. On
|
||||||
|
# repeated Cmake runs, the same message won't be printed again.
|
||||||
|
#
|
||||||
|
# Example for mode 2:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# find_package_handle_standard_args(LibXslt
|
||||||
|
# FOUND_VAR LibXslt_FOUND
|
||||||
|
# REQUIRED_VARS LibXslt_LIBRARIES LibXslt_INCLUDE_DIRS
|
||||||
|
# VERSION_VAR LibXslt_VERSION_STRING)
|
||||||
|
#
|
||||||
|
# In this case, LibXslt is considered to be found if the variable(s)
|
||||||
|
# listed after REQUIRED_VAR are all valid, i.e. LibXslt_LIBRARIES and
|
||||||
|
# LibXslt_INCLUDE_DIRS in this case. The result will then be stored in
|
||||||
|
# LibXslt_FOUND . Also the version of LibXslt will be checked by using
|
||||||
|
# the version contained in LibXslt_VERSION_STRING. Since no
|
||||||
|
# FAIL_MESSAGE is given, the default messages will be printed.
|
||||||
|
#
|
||||||
|
# Another example for mode 2:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
|
||||||
|
# find_package_handle_standard_args(Automoc4 CONFIG_MODE)
|
||||||
|
#
|
||||||
|
# In this case, FindAutmoc4.cmake wraps a call to find_package(Automoc4
|
||||||
|
# NO_MODULE) and adds an additional search directory for automoc4. Here
|
||||||
|
# the result will be stored in AUTOMOC4_FOUND. The following
|
||||||
|
# FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
|
||||||
|
# success/error message.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2007-2009 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)
|
||||||
|
|
||||||
|
# internal helper macro
|
||||||
|
macro(_FPHSA_FAILURE_MESSAGE _msg)
|
||||||
|
if (${_NAME}_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "${_msg}")
|
||||||
|
else ()
|
||||||
|
if (NOT ${_NAME}_FIND_QUIETLY)
|
||||||
|
message(STATUS "${_msg}")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
# internal helper macro to generate the failure message when used in CONFIG_MODE:
|
||||||
|
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
|
||||||
|
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
|
||||||
|
if(${_NAME}_CONFIG)
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
|
||||||
|
else()
|
||||||
|
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
|
||||||
|
# List them all in the error message:
|
||||||
|
if(${_NAME}_CONSIDERED_CONFIGS)
|
||||||
|
set(configsText "")
|
||||||
|
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
|
||||||
|
math(EXPR configsCount "${configsCount} - 1")
|
||||||
|
foreach(currentConfigIndex RANGE ${configsCount})
|
||||||
|
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
|
||||||
|
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
|
||||||
|
set(configsText "${configsText} ${filename} (version ${version})\n")
|
||||||
|
endforeach()
|
||||||
|
if (${_NAME}_NOT_FOUND_MESSAGE)
|
||||||
|
set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n")
|
||||||
|
endif()
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
|
||||||
|
|
||||||
|
else()
|
||||||
|
# Simple case: No Config-file was found at all:
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
|
||||||
|
|
||||||
|
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
|
||||||
|
# new extended or in the "old" mode:
|
||||||
|
set(options CONFIG_MODE HANDLE_COMPONENTS)
|
||||||
|
set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR)
|
||||||
|
set(multiValueArgs REQUIRED_VARS)
|
||||||
|
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
|
||||||
|
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
|
||||||
|
|
||||||
|
if(${INDEX} EQUAL -1)
|
||||||
|
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
|
||||||
|
set(FPHSA_REQUIRED_VARS ${ARGN})
|
||||||
|
set(FPHSA_VERSION_VAR)
|
||||||
|
else()
|
||||||
|
|
||||||
|
CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
|
||||||
|
|
||||||
|
if(FPHSA_UNPARSED_ARGUMENTS)
|
||||||
|
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT FPHSA_FAIL_MESSAGE)
|
||||||
|
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# now that we collected all arguments, process them
|
||||||
|
|
||||||
|
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
|
||||||
|
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
|
||||||
|
# when it successfully found the config-file, including version checking:
|
||||||
|
if(FPHSA_CONFIG_MODE)
|
||||||
|
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
|
||||||
|
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
|
||||||
|
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT FPHSA_REQUIRED_VARS)
|
||||||
|
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
|
||||||
|
|
||||||
|
string(TOUPPER ${_NAME} _NAME_UPPER)
|
||||||
|
string(TOLOWER ${_NAME} _NAME_LOWER)
|
||||||
|
|
||||||
|
if(FPHSA_FOUND_VAR)
|
||||||
|
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
|
||||||
|
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# collect all variables which were not found, so they can be printed, so the
|
||||||
|
# user knows better what went wrong (#6375)
|
||||||
|
set(MISSING_VARS "")
|
||||||
|
set(DETAILS "")
|
||||||
|
# check if all passed variables are valid
|
||||||
|
unset(${_FOUND_VAR})
|
||||||
|
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
|
||||||
|
if(NOT ${_CURRENT_VAR})
|
||||||
|
set(${_FOUND_VAR} FALSE)
|
||||||
|
set(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
|
||||||
|
else()
|
||||||
|
set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(NOT "${${_FOUND_VAR}}" STREQUAL "FALSE")
|
||||||
|
set(${_FOUND_VAR} TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# component handling
|
||||||
|
unset(FOUND_COMPONENTS_MSG)
|
||||||
|
unset(MISSING_COMPONENTS_MSG)
|
||||||
|
|
||||||
|
if(FPHSA_HANDLE_COMPONENTS)
|
||||||
|
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||||
|
if(${_NAME}_${comp}_FOUND)
|
||||||
|
|
||||||
|
if(NOT DEFINED FOUND_COMPONENTS_MSG)
|
||||||
|
set(FOUND_COMPONENTS_MSG "found components: ")
|
||||||
|
endif()
|
||||||
|
set(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
if(NOT DEFINED MISSING_COMPONENTS_MSG)
|
||||||
|
set(MISSING_COMPONENTS_MSG "missing components: ")
|
||||||
|
endif()
|
||||||
|
set(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
|
||||||
|
|
||||||
|
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||||
|
set(${_FOUND_VAR} FALSE)
|
||||||
|
set(MISSING_VARS "${MISSING_VARS} ${comp}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
|
||||||
|
set(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# version handling:
|
||||||
|
set(VERSION_MSG "")
|
||||||
|
set(VERSION_OK TRUE)
|
||||||
|
set(VERSION ${${FPHSA_VERSION_VAR}})
|
||||||
|
|
||||||
|
# check with DEFINED here as the requested or found version may be "0"
|
||||||
|
if (DEFINED ${_NAME}_FIND_VERSION)
|
||||||
|
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||||
|
|
||||||
|
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
|
||||||
|
# count the dots in the version string
|
||||||
|
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}")
|
||||||
|
# add one dot because there is one dot more than there are components
|
||||||
|
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
|
||||||
|
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
|
||||||
|
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
|
||||||
|
# is at most 4 here. Therefore a simple lookup table is used.
|
||||||
|
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
|
||||||
|
set(_VERSION_REGEX "[^.]*")
|
||||||
|
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
|
||||||
|
set(_VERSION_REGEX "[^.]*\\.[^.]*")
|
||||||
|
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
|
||||||
|
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
|
||||||
|
else ()
|
||||||
|
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
|
||||||
|
endif ()
|
||||||
|
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}")
|
||||||
|
unset(_VERSION_REGEX)
|
||||||
|
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
|
||||||
|
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||||
|
set(VERSION_OK FALSE)
|
||||||
|
else ()
|
||||||
|
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
|
||||||
|
endif ()
|
||||||
|
unset(_VERSION_HEAD)
|
||||||
|
else ()
|
||||||
|
if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
|
||||||
|
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||||
|
set(VERSION_OK FALSE)
|
||||||
|
else ()
|
||||||
|
set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
unset(_VERSION_DOTS)
|
||||||
|
|
||||||
|
else() # minimum version specified:
|
||||||
|
if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
|
||||||
|
set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
|
||||||
|
set(VERSION_OK FALSE)
|
||||||
|
else ()
|
||||||
|
set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
|
||||||
|
endif ()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
# if the package was not found, but a version was given, add that to the output:
|
||||||
|
if(${_NAME}_FIND_VERSION_EXACT)
|
||||||
|
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
|
||||||
|
else()
|
||||||
|
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
else ()
|
||||||
|
if(VERSION)
|
||||||
|
set(VERSION_MSG "(found version \"${VERSION}\")")
|
||||||
|
endif()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(VERSION_OK)
|
||||||
|
set(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
|
||||||
|
else()
|
||||||
|
set(${_FOUND_VAR} FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# print the result:
|
||||||
|
if (${_FOUND_VAR})
|
||||||
|
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
|
||||||
|
else ()
|
||||||
|
|
||||||
|
if(FPHSA_CONFIG_MODE)
|
||||||
|
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
|
||||||
|
else()
|
||||||
|
if(NOT VERSION_OK)
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
|
||||||
|
else()
|
||||||
|
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(${_FOUND_VAR} ${${_FOUND_VAR}} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endfunction()
|
57
cmake/FindPackageMessage.cmake
Normal file
57
cmake/FindPackageMessage.cmake
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#.rst:
|
||||||
|
# FindPackageMessage
|
||||||
|
# ------------------
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
|
||||||
|
#
|
||||||
|
# This macro is intended to be used in FindXXX.cmake modules files. It
|
||||||
|
# will print a message once for each unique find result. This is useful
|
||||||
|
# for telling the user where a package was found. The first argument
|
||||||
|
# specifies the name (XXX) of the package. The second argument
|
||||||
|
# specifies the message to display. The third argument lists details
|
||||||
|
# about the find result so that if they change the message will be
|
||||||
|
# displayed again. The macro also obeys the QUIET argument to the
|
||||||
|
# find_package command.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# if(X11_FOUND)
|
||||||
|
# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
|
||||||
|
# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
|
||||||
|
# else()
|
||||||
|
# ...
|
||||||
|
# endif()
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2008-2009 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
function(FIND_PACKAGE_MESSAGE pkg msg details)
|
||||||
|
# Avoid printing a message repeatedly for the same find result.
|
||||||
|
if(NOT ${pkg}_FIND_QUIETLY)
|
||||||
|
string(REPLACE "\n" "" details "${details}")
|
||||||
|
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
|
||||||
|
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
|
||||||
|
# The message has not yet been printed.
|
||||||
|
message(STATUS "${msg}")
|
||||||
|
|
||||||
|
# Save the find details in the cache to avoid printing the same
|
||||||
|
# message again.
|
||||||
|
set("${DETAILS_VAR}" "${details}"
|
||||||
|
CACHE INTERNAL "Details about finding ${pkg}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
47
cmake/FindSolidity.cmake
Normal file
47
cmake/FindSolidity.cmake
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Find Solidity
|
||||||
|
#
|
||||||
|
# Find the solidity includes and library
|
||||||
|
#
|
||||||
|
# This module defines
|
||||||
|
# Solidity_XXX_LIBRARIES, the libraries needed to use solidity.
|
||||||
|
# SOLIDITY_INCLUDE_DIRS
|
||||||
|
|
||||||
|
include(EthUtils)
|
||||||
|
set(LIBS solidity;lll;evmasm)
|
||||||
|
|
||||||
|
set(Solidity_INCLUDE_DIRS "${SOL_DIR}")
|
||||||
|
|
||||||
|
# if the project is a subset of main cpp-ethereum project
|
||||||
|
# use same pattern for variables as Boost uses
|
||||||
|
if ((DEFINED solidity_VERSION) OR (DEFINED cpp-ethereum_VERSION))
|
||||||
|
|
||||||
|
foreach (l ${LIBS})
|
||||||
|
string(TOUPPER ${l} L)
|
||||||
|
set ("Solidity_${L}_LIBRARIES" ${l})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
foreach (l ${LIBS})
|
||||||
|
string(TOUPPER ${l} L)
|
||||||
|
find_library(Solidity_${L}_LIBRARY
|
||||||
|
NAMES ${l}
|
||||||
|
PATHS ${CMAKE_LIBRARY_PATH}
|
||||||
|
PATH_SUFFIXES "lib${l}" "${l}" "lib${l}/Debug" "lib${l}/Release"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
set(Solidity_${L}_LIBRARIES ${Solidity_${L}_LIBRARY})
|
||||||
|
|
||||||
|
if (DEFINED MSVC)
|
||||||
|
find_library(Solidity_${L}_LIBRARY_DEBUG
|
||||||
|
NAMES ${l}
|
||||||
|
PATHS ${CMAKE_LIBRARY_PATH}
|
||||||
|
PATH_SUFFIXES "lib${l}/Debug"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
eth_check_library_link(Solidity_${L})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
endif()
|
30
cmake/UseDev.cmake
Normal file
30
cmake/UseDev.cmake
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function(eth_apply TARGET REQUIRED SUBMODULE)
|
||||||
|
|
||||||
|
# Base is where all dependencies for devcore are
|
||||||
|
if (${SUBMODULE} STREQUAL "base")
|
||||||
|
# if it's ethereum source dir, always build BuildInfo.h before
|
||||||
|
eth_use(${TARGET} ${REQUIRED} Dev::buildinfo)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET} ${Boost_THREAD_LIBRARIES})
|
||||||
|
target_link_libraries(${TARGET} ${Boost_RANDOM_LIBRARIES})
|
||||||
|
target_link_libraries(${TARGET} ${Boost_FILESYSTEM_LIBRARIES})
|
||||||
|
target_link_libraries(${TARGET} ${Boost_SYSTEM_LIBRARIES})
|
||||||
|
|
||||||
|
if (DEFINED MSVC)
|
||||||
|
target_link_libraries(${TARGET} ${Boost_CHRONO_LIBRARIES})
|
||||||
|
target_link_libraries(${TARGET} ${Boost_DATE_TIME_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||||
|
target_link_libraries(${TARGET} pthread)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${SUBMODULE} STREQUAL "devcore")
|
||||||
|
eth_use(${TARGET} ${REQUIRED} Dev::base)
|
||||||
|
target_link_libraries(${TARGET} devcore)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
10
cmake/UseJsoncpp.cmake
Normal file
10
cmake/UseJsoncpp.cmake
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
function(eth_apply TARGET REQUIRED)
|
||||||
|
find_package (Jsoncpp 0.60)
|
||||||
|
eth_show_dependency(JSONCPP JsonCpp)
|
||||||
|
if (JSONCPP_FOUND)
|
||||||
|
target_include_directories(${TARGET} SYSTEM BEFORE PUBLIC ${JSONCPP_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET} ${JSONCPP_LIBRARIES})
|
||||||
|
elseif (NOT ${REQUIRED} STREQUAL "OPTIONAL")
|
||||||
|
message(FATAL_ERROR "Jsoncpp library not found")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
33
cmake/UseSolidity.cmake
Normal file
33
cmake/UseSolidity.cmake
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
function(eth_apply TARGET REQUIRED SUBMODULE)
|
||||||
|
|
||||||
|
set(SOL_DIR "${ETH_CMAKE_DIR}/.." CACHE PATH "The path to the solidity directory")
|
||||||
|
set(SOL_BUILD_DIR_NAME "build" CACHE STRING "The name of the build directory in solidity repo")
|
||||||
|
set(SOL_BUILD_DIR "${SOL_DIR}/${SOL_BUILD_DIR_NAME}")
|
||||||
|
set(CMAKE_LIBRARY_PATH ${SOL_BUILD_DIR};${CMAKE_LIBRARY_PATH})
|
||||||
|
|
||||||
|
find_package(Solidity)
|
||||||
|
|
||||||
|
# Hide confusing blank dependency information when using FindSolidity on itself.
|
||||||
|
if (NOT(${MODULE_MAIN} STREQUAL Solidity))
|
||||||
|
eth_show_dependency(SOLIDITY solidity)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(${TARGET} PUBLIC ${Solidity_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
if (${SUBMODULE} STREQUAL "evmasm")
|
||||||
|
eth_use(${TARGET} ${REQUIRED} )
|
||||||
|
target_link_libraries(${TARGET} ${Solidity_EVMASM_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${SUBMODULE} STREQUAL "lll")
|
||||||
|
eth_use(${TARGET} ${REQUIRED} Solidity::evmasm)
|
||||||
|
target_link_libraries(${TARGET} ${Solidity_LLL_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${SUBMODULE} STREQUAL "solidity" OR ${SUBMODULE} STREQUAL "")
|
||||||
|
eth_use(${TARGET} ${REQUIRED} Dev::devcore Solidity::evmasm)
|
||||||
|
target_link_libraries(${TARGET} ${Solidity_SOLIDITY_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(${TARGET} PUBLIC ETH_SOLIDITY)
|
||||||
|
endfunction()
|
49
cmake/scripts/buildinfo.cmake
Normal file
49
cmake/scripts/buildinfo.cmake
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# generates BuildInfo.h
|
||||||
|
#
|
||||||
|
# this module expects
|
||||||
|
# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR
|
||||||
|
# ETH_DST_DIR - main CMAKE_BINARY_DIR
|
||||||
|
# ETH_BUILD_TYPE
|
||||||
|
# ETH_BUILD_PLATFORM
|
||||||
|
# ETH_BUILD_NUMBER
|
||||||
|
# ETH_VERSION_SUFFIX
|
||||||
|
#
|
||||||
|
# example usage:
|
||||||
|
# cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=Darwin/appleclang -P scripts/buildinfo.cmake
|
||||||
|
|
||||||
|
if (NOT ETH_BUILD_TYPE)
|
||||||
|
set(ETH_BUILD_TYPE "unknown")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT ETH_BUILD_PLATFORM)
|
||||||
|
set(ETH_BUILD_PLATFORM "unknown")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD
|
||||||
|
OUTPUT_VARIABLE ETH_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
|
||||||
|
)
|
||||||
|
|
||||||
|
if (NOT ETH_COMMIT_HASH)
|
||||||
|
set(ETH_COMMIT_HASH 0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff HEAD --shortstat
|
||||||
|
OUTPUT_VARIABLE ETH_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
|
||||||
|
)
|
||||||
|
|
||||||
|
if (ETH_LOCAL_CHANGES)
|
||||||
|
set(ETH_CLEAN_REPO 0)
|
||||||
|
else()
|
||||||
|
set(ETH_CLEAN_REPO 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp")
|
||||||
|
set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h")
|
||||||
|
|
||||||
|
configure_file("${ETH_BUILDINFO_IN}" "${TMPFILE}")
|
||||||
|
|
||||||
|
include("${ETH_CMAKE_DIR}/EthUtils.cmake")
|
||||||
|
replace_if_different("${TMPFILE}" "${OUTFILE}" CREATE)
|
||||||
|
|
11
cmake/templates/BuildInfo.h.in
Normal file
11
cmake/templates/BuildInfo.h.in
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ETH_PROJECT_VERSION "@PROJECT_VERSION@"
|
||||||
|
#define ETH_COMMIT_HASH @ETH_COMMIT_HASH@
|
||||||
|
#define ETH_CLEAN_REPO @ETH_CLEAN_REPO@
|
||||||
|
#define ETH_BUILD_TYPE @ETH_BUILD_TYPE@
|
||||||
|
#define ETH_BUILD_OS @ETH_BUILD_OS@
|
||||||
|
#define ETH_BUILD_COMPILER @ETH_BUILD_COMPILER@
|
||||||
|
#define ETH_BUILD_PLATFORM @ETH_BUILD_PLATFORM@
|
||||||
|
#define ETH_BUILD_NUMBER @ETH_BUILD_NUMBER@
|
||||||
|
#define ETH_VERSION_SUFFIX "@ETH_VERSION_SUFFIX@"
|
1
deps
Submodule
1
deps
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit f2ede70f33633b26a27299ff39995914db2c6923
|
@ -23,6 +23,9 @@ name as the contract) is executed once.
|
|||||||
From ``web3.js``, i.e. the JavaScript
|
From ``web3.js``, i.e. the JavaScript
|
||||||
API, this is done as follows::
|
API, this is done as follows::
|
||||||
|
|
||||||
|
// Need to specify some source including contract name for the data param below
|
||||||
|
var source = "contract CONTRACT_NAME { function CONTRACT_NAME(unit a, uint b) {} }";
|
||||||
|
|
||||||
// The json abi array generated by the compiler
|
// The json abi array generated by the compiler
|
||||||
var abiArray = [
|
var abiArray = [
|
||||||
{
|
{
|
||||||
@ -41,7 +44,8 @@ API, this is done as follows::
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var MyContract = web3.eth.contract(abiArray);
|
var MyContract_ = web3.eth.contract(source);
|
||||||
|
MyContract = web3.eth.contract(MyContract_.CONTRACT_NAME.info.abiDefinition);
|
||||||
// deploy new contract
|
// deploy new contract
|
||||||
var contractInstance = MyContract.new(
|
var contractInstance = MyContract.new(
|
||||||
10,
|
10,
|
||||||
@ -85,7 +89,7 @@ This means that cyclic creation dependencies are impossible.
|
|||||||
// Only the creator can alter the name --
|
// Only the creator can alter the name --
|
||||||
// the comparison is possible since contracts
|
// the comparison is possible since contracts
|
||||||
// are implicitly convertible to addresses.
|
// are implicitly convertible to addresses.
|
||||||
if (msg.sender == creator)
|
if (msg.sender == address(creator))
|
||||||
name = newName;
|
name = newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ The evaluation order of expressions is not specified (more formally, the order
|
|||||||
in which the children of one node in the expression tree are evaluated is not
|
in which the children of one node in the expression tree are evaluated is not
|
||||||
specified, but they are of course evaluated before the node itself). It is only
|
specified, but they are of course evaluated before the node itself). It is only
|
||||||
guaranteed that statements are executed in order and short-circuiting for
|
guaranteed that statements are executed in order and short-circuiting for
|
||||||
boolean expressions is done.
|
boolean expressions is done. See :ref:`order` for more information.
|
||||||
|
|
||||||
.. index:: ! assignment
|
.. index:: ! assignment
|
||||||
|
|
||||||
|
@ -38,9 +38,6 @@ Available Solidity Integrations
|
|||||||
* `Visual Studio Extension <https://visualstudiogallery.msdn.microsoft.com/96221853-33c4-4531-bdd5-d2ea5acc4799/>`_
|
* `Visual Studio Extension <https://visualstudiogallery.msdn.microsoft.com/96221853-33c4-4531-bdd5-d2ea5acc4799/>`_
|
||||||
Solidity plugin for Microsoft Visual Studio that includes the Solidity compiler.
|
Solidity plugin for Microsoft Visual Studio that includes the Solidity compiler.
|
||||||
|
|
||||||
* `Mix IDE <https://github.com/ethereum/mix/>`_
|
|
||||||
Qt based IDE for designing, debugging and testing solidity smart contracts.
|
|
||||||
|
|
||||||
* `Package for SublimeText — Solidity language syntax <https://packagecontrol.io/packages/Ethereum/>`_
|
* `Package for SublimeText — Solidity language syntax <https://packagecontrol.io/packages/Ethereum/>`_
|
||||||
Solidity syntax highlighting for SublimeText editor.
|
Solidity syntax highlighting for SublimeText editor.
|
||||||
|
|
||||||
@ -59,6 +56,12 @@ Available Solidity Integrations
|
|||||||
* `Vim Solidity <https://github.com/tomlion/vim-solidity/>`_
|
* `Vim Solidity <https://github.com/tomlion/vim-solidity/>`_
|
||||||
Plugin for the Vim editor providing syntax highlighting.
|
Plugin for the Vim editor providing syntax highlighting.
|
||||||
|
|
||||||
|
Discontinued:
|
||||||
|
|
||||||
|
* `Mix IDE <https://github.com/ethereum/mix/>`_
|
||||||
|
Qt based IDE for designing, debugging and testing solidity smart contracts.
|
||||||
|
|
||||||
|
|
||||||
Solidity Tools
|
Solidity Tools
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ index mentioned above.
|
|||||||
The encoding in the source mapping for the bytecode is more complicated:
|
The encoding in the source mapping for the bytecode is more complicated:
|
||||||
It is a list of ``s:l:f:j`` separated by ``;``. Each of these
|
It is a list of ``s:l:f:j`` separated by ``;``. Each of these
|
||||||
elements corresponds to an instruction, i.e. you cannot use the byte offset
|
elements corresponds to an instruction, i.e. you cannot use the byte offset
|
||||||
but have to use the instruction offset or PC (program counter).
|
but have to use the instruction offset (push instructions are longer than a single byte).
|
||||||
The fields ``s``, ``l`` and ``f`` are as above and ``j`` can be either
|
The fields ``s``, ``l`` and ``f`` are as above and ``j`` can be either
|
||||||
``i``, ``o`` or ``-`` signifying whether a jump instruction goes into a
|
``i``, ``o`` or ``-`` signifying whether a jump instruction goes into a
|
||||||
function, returns from a function or is a regular jump as part of e.g. a loop.
|
function, returns from a function or is a regular jump as part of e.g. a loop.
|
||||||
@ -202,6 +202,69 @@ Tips and Tricks
|
|||||||
Cheatsheet
|
Cheatsheet
|
||||||
**********
|
**********
|
||||||
|
|
||||||
|
.. index:: precedence
|
||||||
|
|
||||||
|
.. _order:
|
||||||
|
|
||||||
|
Order of Precedence of Operators
|
||||||
|
================================
|
||||||
|
|
||||||
|
The following is the order of precedence for operators, listed in order of evaluation.
|
||||||
|
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| Precedence | Description | Operator |
|
||||||
|
+============+=====================================+============================================+
|
||||||
|
| *1* | Postfix increment and decrement | ``++``, ``--`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Function-like call | ``<func>(<args...>)`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Array subscripting | ``<array>[<index>]`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Member access | ``<object>.<member>`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Parentheses | ``(<statement>)`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *2* | Prefix increment and decrement | ``++``, ``--`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Unary plus and minus | ``+``, ``-`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Unary operations | ``after``, ``delete`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Logical NOT | ``!`` |
|
||||||
|
+ +-------------------------------------+--------------------------------------------+
|
||||||
|
| | Bitwise NOT | ``~`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *3* | Exponentiation | ``**`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *4* | Multiplication, division and modulo | ``*``, ``/``, ``%`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *5* | Addition and subtraction | ``+``, ``-`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *6* | Bitwise shift operators | ``<<``, ``>>`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *7* | Bitwise AND | ``&`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *8* | Bitwise XOR | ``^`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *9* | Bitwise OR | ``|`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *10* | Inequality operators | ``<``, ``>``, ``<=``, ``>=`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *11* | Equality operators | ``==``, ``!=`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *12* | Logical AND | ``&&`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *13* | Logical OR | ``||`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *14* | Ternary operator | ``<conditional> ? <if-true> : <if-false>`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *15* | Assignment operators | ``=``, ``|=``, ``^=``, ``&=``, ``<<=``, |
|
||||||
|
| | | ``>>=``, ``+=``, ``-=``, ``*=``, ``/=``, |
|
||||||
|
| | | ``%=`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
| *16* | Comma operator | ``,`` |
|
||||||
|
+------------+-------------------------------------+--------------------------------------------+
|
||||||
|
|
||||||
.. index:: block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin, sha3, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send
|
.. index:: block, coinbase, difficulty, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, now, gas price, origin, sha3, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, this, super, selfdestruct, balance, send
|
||||||
|
|
||||||
Global Variables
|
Global Variables
|
||||||
|
@ -640,7 +640,7 @@ words. (for example:``MAX_BLOCKS``)
|
|||||||
Modifiers
|
Modifiers
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Function modifiers should use lowercase words separated by underscores.
|
Use mixedCase.
|
||||||
|
|
||||||
|
|
||||||
Avoiding Collisions
|
Avoiding Collisions
|
||||||
|
@ -12,6 +12,9 @@ see :ref:`type-deduction` below) at
|
|||||||
compile-time. Solidity provides several elementary types which can be combined
|
compile-time. Solidity provides several elementary types which can be combined
|
||||||
to form complex types.
|
to form complex types.
|
||||||
|
|
||||||
|
In addition, types can interact with each other in expressions containing
|
||||||
|
operators. For a quick reference of the various operators, see :ref:`order`.
|
||||||
|
|
||||||
.. index:: ! value type, ! type;value
|
.. index:: ! value type, ! type;value
|
||||||
|
|
||||||
Value Types
|
Value Types
|
||||||
@ -542,7 +545,8 @@ shown in the following example:
|
|||||||
Campaign c = campaigns[campaignID];
|
Campaign c = campaigns[campaignID];
|
||||||
if (c.amount < c.fundingGoal)
|
if (c.amount < c.fundingGoal)
|
||||||
return false;
|
return false;
|
||||||
c.beneficiary.send(c.amount);
|
if (!c.beneficiary.send(c.amount))
|
||||||
|
throw;
|
||||||
c.amount = 0;
|
c.amount = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -ev
|
|
||||||
|
|
||||||
if [[ "$OSTYPE" != "darwin"* ]]
|
|
||||||
then
|
|
||||||
cd docs && sphinx-build -nW -b html -d _build/doctrees . _build/html && cd ..
|
|
||||||
fi
|
|
||||||
|
|
||||||
SUBREPO=solidity
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
git clone --depth 3 -b develop https://github.com/ethereum/tests.git
|
|
||||||
export ETHEREUM_TEST_PATH=$(pwd)/tests/
|
|
||||||
git clone --recursive -b develop https://github.com/ethereum/webthree-umbrella.git
|
|
||||||
cd webthree-umbrella
|
|
||||||
rm -rf $SUBREPO
|
|
||||||
mv ../$SUBREPO .
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
OPTIONS=""
|
|
||||||
if [[ "$OSTYPE" != "darwin"* ]]
|
|
||||||
then
|
|
||||||
OPTIONS="-DCMAKE_C_COMPILER=/usr/lib/ccache/$CC -DCMAKE_CXX_COMPILER=/usr/lib/ccache/$CXX"
|
|
||||||
fi
|
|
||||||
cmake .. -DGUI=0 -DCMAKE_BUILD_TYPE=$TRAVIS_BUILD_TYPE $OPTIONS
|
|
||||||
make lllc solc soljson soltest
|
|
||||||
|
|
||||||
|
|
||||||
# Test runs disabled for macos for now,
|
|
||||||
# we need to find a way to install eth.
|
|
||||||
if [[ "$OSTYPE" != "darwin"* ]]
|
|
||||||
then
|
|
||||||
eth --test -d /tmp/test &
|
|
||||||
while [ ! -S /tmp/test/geth.ipc ]; do sleep 2; done
|
|
||||||
|
|
||||||
./solidity/test/soltest --ipc /tmp/test/geth.ipc
|
|
||||||
pkill eth
|
|
||||||
fi
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# Bash script for installing pre-requisite packages for cpp-ethereum.
|
|
||||||
#
|
|
||||||
# The documentation for cpp-ethereum is hosted at:
|
|
||||||
#
|
|
||||||
# http://www.ethdocs.org/en/latest/ethereum-clients/cpp-ethereum/
|
|
||||||
#
|
|
||||||
# (c) 2016 cpp-ethereum contributors.
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
|
|
||||||
if echo `sw_vers` | grep "10.11"; then
|
|
||||||
echo OS X El Capitan detected
|
|
||||||
elif echo `sw_vers` | grep "10.10"; then
|
|
||||||
echo OS X Yosemite detected
|
|
||||||
else
|
|
||||||
echo Unsupported OS X version. We only support Yosemite and El Capitan.
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
brew update
|
|
||||||
brew upgrade
|
|
||||||
|
|
||||||
brew install boost
|
|
||||||
brew install cmake
|
|
||||||
brew install cryptopp
|
|
||||||
brew install miniupnpc
|
|
||||||
brew install leveldb
|
|
||||||
brew install gmp
|
|
||||||
brew install jsoncpp
|
|
||||||
brew install libmicrohttpd
|
|
||||||
brew install libjson-rpc-cpp
|
|
||||||
brew install homebrew/versions/llvm37
|
|
||||||
|
|
||||||
elif [[ "$OSTYPE" == "linux-gnu" ]]; then
|
|
||||||
|
|
||||||
# NOTE - These steps are ONLY correct for Ubuntu Trusty. We need to add
|
|
||||||
# further conditionals in here for the other Ubuntu versions, and carry on
|
|
||||||
# from there if we then want to get this pattern working for Debian,
|
|
||||||
# OpenSUSE, Fedora, Arch Linux, Raspian, FreeBSD, etc.
|
|
||||||
|
|
||||||
# Add additional PPAs which we need to be able to build cpp-ethereum on
|
|
||||||
# Ubuntu Trusty. That includes our own PPAs and a PPA for getting CMake 3.x
|
|
||||||
# on Trusty.
|
|
||||||
sudo add-apt-repository -y ppa:ethereum/ethereum
|
|
||||||
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
|
|
||||||
sudo apt-add-repository -y ppa:george-edison55/cmake-3.x
|
|
||||||
sudo apt-get -y update
|
|
||||||
|
|
||||||
# Install binaries for nearly all of our dependencies
|
|
||||||
sudo apt-get -y install \
|
|
||||||
python-sphinx \
|
|
||||||
build-essential \
|
|
||||||
cmake \
|
|
||||||
git \
|
|
||||||
libboost-all-dev \
|
|
||||||
libcurl4-openssl-dev \
|
|
||||||
libcryptopp-dev \
|
|
||||||
libgmp-dev \
|
|
||||||
libjsoncpp-dev \
|
|
||||||
libleveldb-dev \
|
|
||||||
libmicrohttpd-dev \
|
|
||||||
libminiupnpc-dev \
|
|
||||||
libz-dev \
|
|
||||||
opencl-headers \
|
|
||||||
eth
|
|
||||||
|
|
||||||
# The exception is libjson-rpc-cpp, which we have to build from source for
|
|
||||||
# reliable results. The only binaries available for this package are those
|
|
||||||
# we made ourselves against the (now very old) v0.4.2 release, which are unreliable,
|
|
||||||
# so instead we build the latest release label (v0.6.0) from source, which works just
|
|
||||||
# fine. We should update our PPA.
|
|
||||||
#
|
|
||||||
# See https://github.com/ethereum/webthree-umbrella/issues/513
|
|
||||||
#
|
|
||||||
# Hmm. Arachnid is still getting this issue on OS X, which already has v0.6.0, so
|
|
||||||
# it isn't as simple as just updating all our builds to that version, though that is
|
|
||||||
# sufficient for us to get CircleCI and TravisCI working. We still haven't got to
|
|
||||||
# the bottom of this issue, and are going to need to debug it in some scenario where
|
|
||||||
# we can reproduce it 100%, which MIGHT end up being within our automation here, but
|
|
||||||
# against a build-from-source-with-extra-printfs() of v0.4.2.
|
|
||||||
sudo apt-get -y install libargtable2-dev libedit-dev
|
|
||||||
git clone git://github.com/cinemast/libjson-rpc-cpp.git
|
|
||||||
cd libjson-rpc-cpp
|
|
||||||
git checkout v0.6.0
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -DCOMPILE_TESTS=NO
|
|
||||||
make
|
|
||||||
sudo make install
|
|
||||||
sudo ldconfig
|
|
||||||
cd ../..
|
|
||||||
|
|
||||||
# And install the English language package and reconfigure the locales.
|
|
||||||
# We really shouldn't need to do this, and should instead force our locales to "C"
|
|
||||||
# within our application runtimes, because this issue shows up on multiple Linux distros,
|
|
||||||
# and each will need fixing in the install steps, where we should really just fix it once
|
|
||||||
# in the code.
|
|
||||||
#
|
|
||||||
# See https://github.com/ethereum/webthree-umbrella/issues/169
|
|
||||||
sudo apt-get -y install language-pack-en-base
|
|
||||||
sudo dpkg-reconfigure locales
|
|
||||||
|
|
||||||
fi
|
|
100
libdevcore/ABI.h
Normal file
100
libdevcore/ABI.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file ABI.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libdevcore/Common.h>
|
||||||
|
#include <libdevcore/FixedHash.h>
|
||||||
|
#include <libdevcore/CommonData.h>
|
||||||
|
#include <libdevcore/SHA3.h>
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
namespace eth
|
||||||
|
{
|
||||||
|
|
||||||
|
inline string32 toString32(std::string const& _s)
|
||||||
|
{
|
||||||
|
string32 ret;
|
||||||
|
for (unsigned i = 0; i < 32; ++i)
|
||||||
|
ret[i] = i < _s.size() ? _s[i] : 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct ABISerialiser {};
|
||||||
|
template <unsigned N> struct ABISerialiser<FixedHash<N>> { static bytes serialise(FixedHash<N> const& _t) { static_assert(N <= 32, "Cannot serialise hash > 32 bytes."); static_assert(N > 0, "Cannot serialise zero-length hash."); return bytes(32 - N, 0) + _t.asBytes(); } };
|
||||||
|
template <> struct ABISerialiser<u256> { static bytes serialise(u256 const& _t) { return h256(_t).asBytes(); } };
|
||||||
|
template <> struct ABISerialiser<u160> { static bytes serialise(u160 const& _t) { return bytes(12, 0) + h160(_t).asBytes(); } };
|
||||||
|
template <> struct ABISerialiser<string32> { static bytes serialise(string32 const& _t) { bytes ret; bytesConstRef((byte const*)_t.data(), 32).populate(bytesRef(&ret)); return ret; } };
|
||||||
|
template <> struct ABISerialiser<std::string>
|
||||||
|
{
|
||||||
|
static bytes serialise(std::string const& _t)
|
||||||
|
{
|
||||||
|
bytes ret = h256(u256(32)).asBytes() + h256(u256(_t.size())).asBytes();
|
||||||
|
ret.resize(ret.size() + (_t.size() + 31) / 32 * 32);
|
||||||
|
bytesConstRef(&_t).populate(bytesRef(&ret).cropped(64));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bytes abiInAux() { return {}; }
|
||||||
|
template <class T, class ... U> bytes abiInAux(T const& _t, U const& ... _u)
|
||||||
|
{
|
||||||
|
return ABISerialiser<T>::serialise(_t) + abiInAux(_u ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ... T> bytes abiIn(std::string _id, T const& ... _t)
|
||||||
|
{
|
||||||
|
return sha3(_id).ref().cropped(0, 4).toBytes() + abiInAux(_t ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct ABIDeserialiser {};
|
||||||
|
template <unsigned N> struct ABIDeserialiser<FixedHash<N>> { static FixedHash<N> deserialise(bytesConstRef& io_t) { static_assert(N <= 32, "Parameter sizes must be at most 32 bytes."); FixedHash<N> ret; io_t.cropped(32 - N, N).populate(ret.ref()); io_t = io_t.cropped(32); return ret; } };
|
||||||
|
template <> struct ABIDeserialiser<u256> { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian<u256>(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } };
|
||||||
|
template <> struct ABIDeserialiser<u160> { static u160 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian<u160>(io_t.cropped(12, 20)); io_t = io_t.cropped(32); return ret; } };
|
||||||
|
template <> struct ABIDeserialiser<string32> { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(bytesRef((byte*)ret.data(), 32)); io_t = io_t.cropped(32); return ret; } };
|
||||||
|
template <> struct ABIDeserialiser<std::string>
|
||||||
|
{
|
||||||
|
static std::string deserialise(bytesConstRef& io_t)
|
||||||
|
{
|
||||||
|
unsigned o = (uint16_t)u256(h256(io_t.cropped(0, 32)));
|
||||||
|
unsigned s = (uint16_t)u256(h256(io_t.cropped(o, 32)));
|
||||||
|
std::string ret;
|
||||||
|
ret.resize(s);
|
||||||
|
io_t.cropped(o + 32, s).populate(bytesRef((byte*)ret.data(), s));
|
||||||
|
io_t = io_t.cropped(32);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> T abiOut(bytes const& _data)
|
||||||
|
{
|
||||||
|
bytesConstRef o(&_data);
|
||||||
|
return ABIDeserialiser<T>::deserialise(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> T abiOut(bytesConstRef& _data)
|
||||||
|
{
|
||||||
|
return ABIDeserialiser<T>::deserialise(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
111
libdevcore/Assertions.h
Normal file
111
libdevcore/Assertions.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file Assertions.h
|
||||||
|
* @author Christian <c@ethdev.com>
|
||||||
|
* @date 2015
|
||||||
|
*
|
||||||
|
* Assertion handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Exceptions.h"
|
||||||
|
#include "debugbreak.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define ETH_FUNC __FUNCSIG__
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define ETH_FUNC __PRETTY_FUNCTION__
|
||||||
|
#else
|
||||||
|
#define ETH_FUNC __func__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define asserts(A) ::dev::assertAux(A, #A, __LINE__, __FILE__, ETH_FUNC)
|
||||||
|
#define assertsEqual(A, B) ::dev::assertEqualAux(A, B, #A, #B, __LINE__, __FILE__, ETH_FUNC)
|
||||||
|
|
||||||
|
inline bool assertAux(bool _a, char const* _aStr, unsigned _line, char const* _file, char const* _func)
|
||||||
|
{
|
||||||
|
bool ret = _a;
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
std::cerr << "Assertion failed:" << _aStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
|
||||||
|
#if ETH_DEBUG
|
||||||
|
debug_break();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class A, class B>
|
||||||
|
inline bool assertEqualAux(A const& _a, B const& _b, char const* _aStr, char const* _bStr, unsigned _line, char const* _file, char const* _func)
|
||||||
|
{
|
||||||
|
bool ret = _a == _b;
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
std::cerr << "Assertion failed: " << _aStr << " == " << _bStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
|
||||||
|
std::cerr << " Fail equality: " << _a << "==" << _b << std::endl;
|
||||||
|
#if ETH_DEBUG
|
||||||
|
debug_break();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assertion that throws an exception containing the given description if it is not met.
|
||||||
|
/// Use it as assertThrow(1 == 1, ExceptionType, "Mathematics is wrong.");
|
||||||
|
/// Do NOT supply an exception object as the second parameter.
|
||||||
|
#define assertThrow(_condition, _ExceptionType, _description) \
|
||||||
|
::dev::assertThrowAux<_ExceptionType>(_condition, _description, __LINE__, __FILE__, ETH_FUNC)
|
||||||
|
|
||||||
|
using errinfo_comment = boost::error_info<struct tag_comment, std::string>;
|
||||||
|
|
||||||
|
template <class _ExceptionType>
|
||||||
|
inline void assertThrowAux(
|
||||||
|
bool _condition,
|
||||||
|
::std::string const& _errorDescription,
|
||||||
|
unsigned _line,
|
||||||
|
char const* _file,
|
||||||
|
char const* _function
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!_condition)
|
||||||
|
::boost::throw_exception(
|
||||||
|
_ExceptionType() <<
|
||||||
|
::dev::errinfo_comment(_errorDescription) <<
|
||||||
|
::boost::throw_function(_function) <<
|
||||||
|
::boost::throw_file(_file) <<
|
||||||
|
::boost::throw_line(_line)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _ExceptionType>
|
||||||
|
inline void assertThrowAux(
|
||||||
|
void const* _pointer,
|
||||||
|
::std::string const& _errorDescription,
|
||||||
|
unsigned _line,
|
||||||
|
char const* _file,
|
||||||
|
char const* _function
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assertThrowAux<_ExceptionType>(_pointer != nullptr, _errorDescription, _line, _file, _function);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
146
libdevcore/Base64.cpp
Normal file
146
libdevcore/Base64.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
base64.cpp and base64.h
|
||||||
|
|
||||||
|
Copyright (C) 2004-2008 René Nyffenegger
|
||||||
|
|
||||||
|
This source code is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the author be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this source code must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original source code. If you use this source code
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original source code.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||||
|
*/
|
||||||
|
/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c
|
||||||
|
/// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood.
|
||||||
|
|
||||||
|
#include "Base64.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
static inline bool is_base64(byte c)
|
||||||
|
{
|
||||||
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline byte find_base64_char_index(byte c)
|
||||||
|
{
|
||||||
|
if ('A' <= c && c <= 'Z') return c - 'A';
|
||||||
|
else if ('a' <= c && c <= 'z') return c - 'a' + 1 + find_base64_char_index('Z');
|
||||||
|
else if ('0' <= c && c <= '9') return c - '0' + 1 + find_base64_char_index('z');
|
||||||
|
else if (c == '+') return 1 + find_base64_char_index('9');
|
||||||
|
else if (c == '/') return 1 + find_base64_char_index('+');
|
||||||
|
else return 1 + find_base64_char_index('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
string dev::toBase64(bytesConstRef _in)
|
||||||
|
{
|
||||||
|
static const char base64_chars[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
|
||||||
|
string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
byte char_array_3[3];
|
||||||
|
byte char_array_4[4];
|
||||||
|
|
||||||
|
auto buf = _in.data();
|
||||||
|
auto bufLen = _in.size();
|
||||||
|
|
||||||
|
while (bufLen--)
|
||||||
|
{
|
||||||
|
char_array_3[i++] = *(buf++);
|
||||||
|
if (i == 3)
|
||||||
|
{
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
ret += base64_chars[char_array_4[i]];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
for (j = i; j < 3; j++)
|
||||||
|
char_array_3[j] = '\0';
|
||||||
|
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for (j = 0; j < i + 1; j++)
|
||||||
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
|
||||||
|
while (i++ < 3)
|
||||||
|
ret += '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes dev::fromBase64(string const& encoded_string)
|
||||||
|
{
|
||||||
|
auto in_len = encoded_string.size();
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
int in_ = 0;
|
||||||
|
byte char_array_3[3];
|
||||||
|
byte char_array_4[4];
|
||||||
|
bytes ret;
|
||||||
|
|
||||||
|
while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))
|
||||||
|
{
|
||||||
|
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||||
|
if (i == 4)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
char_array_4[i] = find_base64_char_index(char_array_4[i]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (i = 0; (i < 3); i++)
|
||||||
|
ret.push_back(char_array_3[i]);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
for (j = i; j < 4; j++)
|
||||||
|
char_array_4[j] = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
char_array_4[j] = find_base64_char_index(char_array_4[j]);
|
||||||
|
|
||||||
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||||
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||||
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||||
|
|
||||||
|
for (j = 0; j < i - 1; j++)
|
||||||
|
ret.push_back(char_array_3[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
42
libdevcore/Base64.h
Normal file
42
libdevcore/Base64.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
base64.cpp and base64.h
|
||||||
|
|
||||||
|
Copyright (C) 2004-2008 René Nyffenegger
|
||||||
|
|
||||||
|
This source code is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the author be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this source code must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original source code. If you use this source code
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original source code.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||||
|
*/
|
||||||
|
/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c
|
||||||
|
/// Originally by René Nyffenegger.
|
||||||
|
/// DEVified by Gav Wood.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Common.h"
|
||||||
|
#include "FixedHash.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string toBase64(bytesConstRef _in);
|
||||||
|
bytes fromBase64(std::string const& _in);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
16
libdevcore/CMakeLists.txt
Normal file
16
libdevcore/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
|
||||||
|
|
||||||
|
aux_source_directory(. SRC_LIST)
|
||||||
|
|
||||||
|
set(EXECUTABLE devcore)
|
||||||
|
|
||||||
|
file(GLOB HEADERS "*.h")
|
||||||
|
|
||||||
|
include_directories(..)
|
||||||
|
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
|
||||||
|
|
||||||
|
eth_use(${EXECUTABLE} REQUIRED Jsoncpp Dev::base)
|
||||||
|
|
||||||
|
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
|
||||||
|
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
|
||||||
|
|
27
libdevcore/Common.cpp
Normal file
27
libdevcore/Common.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file Common.cpp
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
const u256 Invalid256 = ~(u256)0;
|
||||||
|
}
|
210
libdevcore/Common.h
Normal file
210
libdevcore/Common.h
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file Common.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*
|
||||||
|
* Very common stuff (i.e. that every other header needs except vector_ref.h).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// way to many unsigned to size_t warnings in 32 bit build
|
||||||
|
#ifdef _M_IX86
|
||||||
|
#pragma warning(disable:4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _MSC_VER && _MSC_VER < 1900
|
||||||
|
#define _ALLOW_KEYWORD_MACROS
|
||||||
|
#define noexcept throw()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __INTEL_COMPILER
|
||||||
|
#pragma warning(disable:3682) //call through incomplete class
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
#endif // defined(__GNUC__)
|
||||||
|
|
||||||
|
// See https://github.com/ethereum/libweb3core/commit/90680a8c25bfb48b24371b4abcacde56c181517c
|
||||||
|
// See https://svn.boost.org/trac/boost/ticket/11328
|
||||||
|
// Bob comment - perhaps we should just HARD FAIL here with Boost-1.58.00?
|
||||||
|
// It is quite old now, and requiring end-users to use a newer Boost release is probably not unreasonable.
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#if (BOOST_VERSION == 105800)
|
||||||
|
#include "boost_multiprecision_number_compare_bug_workaround.hpp"
|
||||||
|
#endif // (BOOST_VERSION == 105800)
|
||||||
|
|
||||||
|
#include <boost/multiprecision/cpp_int.hpp>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif // defined(__GNUC__)
|
||||||
|
|
||||||
|
#include "vector_ref.h"
|
||||||
|
|
||||||
|
// CryptoPP defines byte in the global namespace, so must we.
|
||||||
|
using byte = uint8_t;
|
||||||
|
|
||||||
|
// Quote a given token stream to turn it into a string.
|
||||||
|
#define DEV_QUOTED_HELPER(s) #s
|
||||||
|
#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s)
|
||||||
|
|
||||||
|
#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {}
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
// Binary data types.
|
||||||
|
using bytes = std::vector<byte>;
|
||||||
|
using bytesRef = vector_ref<byte>;
|
||||||
|
using bytesConstRef = vector_ref<byte const>;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class secure_vector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
secure_vector() {}
|
||||||
|
secure_vector(secure_vector<T> const& /*_c*/) = default; // See https://github.com/ethereum/libweb3core/pull/44
|
||||||
|
explicit secure_vector(unsigned _size): m_data(_size) {}
|
||||||
|
explicit secure_vector(unsigned _size, T _item): m_data(_size, _item) {}
|
||||||
|
explicit secure_vector(std::vector<T> const& _c): m_data(_c) {}
|
||||||
|
explicit secure_vector(vector_ref<T> _c): m_data(_c.data(), _c.data() + _c.size()) {}
|
||||||
|
explicit secure_vector(vector_ref<const T> _c): m_data(_c.data(), _c.data() + _c.size()) {}
|
||||||
|
~secure_vector() { ref().cleanse(); }
|
||||||
|
|
||||||
|
secure_vector<T>& operator=(secure_vector<T> const& _c)
|
||||||
|
{
|
||||||
|
if (&_c == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
ref().cleanse();
|
||||||
|
m_data = _c.m_data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
std::vector<T>& writable() { clear(); return m_data; }
|
||||||
|
std::vector<T> const& makeInsecure() const { return m_data; }
|
||||||
|
|
||||||
|
void clear() { ref().cleanse(); }
|
||||||
|
|
||||||
|
vector_ref<T> ref() { return vector_ref<T>(&m_data); }
|
||||||
|
vector_ref<T const> ref() const { return vector_ref<T const>(&m_data); }
|
||||||
|
|
||||||
|
size_t size() const { return m_data.size(); }
|
||||||
|
bool empty() const { return m_data.empty(); }
|
||||||
|
|
||||||
|
void swap(secure_vector<T>& io_other) { m_data.swap(io_other.m_data); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<T> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
using bytesSec = secure_vector<byte>;
|
||||||
|
|
||||||
|
// Numeric types.
|
||||||
|
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
|
||||||
|
using u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using s160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using s512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
using u256s = std::vector<u256>;
|
||||||
|
using u160s = std::vector<u160>;
|
||||||
|
using u256Set = std::set<u256>;
|
||||||
|
using u160Set = std::set<u160>;
|
||||||
|
|
||||||
|
// Map types.
|
||||||
|
using StringMap = std::map<std::string, std::string>;
|
||||||
|
|
||||||
|
// Hash types.
|
||||||
|
using StringHashMap = std::unordered_map<std::string, std::string>;
|
||||||
|
|
||||||
|
// String types.
|
||||||
|
using strings = std::vector<std::string>;
|
||||||
|
// Fixed-length string types.
|
||||||
|
using string32 = std::array<char, 32>;
|
||||||
|
|
||||||
|
// Null/Invalid values for convenience.
|
||||||
|
static const bytes NullBytes;
|
||||||
|
extern const u256 Invalid256;
|
||||||
|
|
||||||
|
/// Interprets @a _u as a two's complement signed number and returns the resulting s256.
|
||||||
|
inline s256 u2s(u256 _u)
|
||||||
|
{
|
||||||
|
static const bigint c_end = bigint(1) << 256;
|
||||||
|
if (boost::multiprecision::bit_test(_u, 255))
|
||||||
|
return s256(-(c_end - _u));
|
||||||
|
else
|
||||||
|
return s256(_u);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @returns the two's complement signed representation of the signed number _u.
|
||||||
|
inline u256 s2u(s256 _u)
|
||||||
|
{
|
||||||
|
static const bigint c_end = bigint(1) << 256;
|
||||||
|
if (_u >= 0)
|
||||||
|
return u256(_u);
|
||||||
|
else
|
||||||
|
return u256(c_end + _u);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t n> inline u256 exp10()
|
||||||
|
{
|
||||||
|
return exp10<n - 1>() * u256(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline u256 exp10<0>()
|
||||||
|
{
|
||||||
|
return u256(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// RAII utility class whose destructor calls a given function.
|
||||||
|
class ScopeGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopeGuard(std::function<void(void)> _f): m_f(_f) {}
|
||||||
|
~ScopeGuard() { m_f(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(void)> m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class WithExisting: int
|
||||||
|
{
|
||||||
|
Trust = 0,
|
||||||
|
Verify,
|
||||||
|
Rescue,
|
||||||
|
Kill
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
107
libdevcore/CommonData.cpp
Normal file
107
libdevcore/CommonData.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file CommonData.cpp
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CommonData.h"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4724) // potential mod by 0, line 78 of boost/random/uniform_int_distribution.hpp (boost 1.55)
|
||||||
|
#endif
|
||||||
|
#include <boost/random/uniform_int_distribution.hpp>
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
#include "Exceptions.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
std::string dev::escaped(std::string const& _s, bool _all)
|
||||||
|
{
|
||||||
|
static const map<char, char> prettyEscapes{{'\r', 'r'}, {'\n', 'n'}, {'\t', 't'}, {'\v', 'v'}};
|
||||||
|
std::string ret;
|
||||||
|
ret.reserve(_s.size() + 2);
|
||||||
|
ret.push_back('"');
|
||||||
|
for (auto i: _s)
|
||||||
|
if (i == '"' && !_all)
|
||||||
|
ret += "\\\"";
|
||||||
|
else if (i == '\\' && !_all)
|
||||||
|
ret += "\\\\";
|
||||||
|
else if (prettyEscapes.count(i) && !_all)
|
||||||
|
{
|
||||||
|
ret += '\\';
|
||||||
|
ret += prettyEscapes.find(i)->second;
|
||||||
|
}
|
||||||
|
else if (i < ' ' || _all)
|
||||||
|
{
|
||||||
|
ret += "\\x";
|
||||||
|
ret.push_back("0123456789abcdef"[(uint8_t)i / 16]);
|
||||||
|
ret.push_back("0123456789abcdef"[(uint8_t)i % 16]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret.push_back(i);
|
||||||
|
ret.push_back('"');
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dev::fromHex(char _i, WhenError _throw)
|
||||||
|
{
|
||||||
|
if (_i >= '0' && _i <= '9')
|
||||||
|
return _i - '0';
|
||||||
|
if (_i >= 'a' && _i <= 'f')
|
||||||
|
return _i - 'a' + 10;
|
||||||
|
if (_i >= 'A' && _i <= 'F')
|
||||||
|
return _i - 'A' + 10;
|
||||||
|
if (_throw == WhenError::Throw)
|
||||||
|
BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i));
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes dev::fromHex(std::string const& _s, WhenError _throw)
|
||||||
|
{
|
||||||
|
unsigned s = (_s.size() >= 2 && _s[0] == '0' && _s[1] == 'x') ? 2 : 0;
|
||||||
|
std::vector<uint8_t> ret;
|
||||||
|
ret.reserve((_s.size() - s + 1) / 2);
|
||||||
|
|
||||||
|
if (_s.size() % 2)
|
||||||
|
{
|
||||||
|
int h = fromHex(_s[s++], WhenError::DontThrow);
|
||||||
|
if (h != -1)
|
||||||
|
ret.push_back(h);
|
||||||
|
else if (_throw == WhenError::Throw)
|
||||||
|
BOOST_THROW_EXCEPTION(BadHexCharacter());
|
||||||
|
else
|
||||||
|
return bytes();
|
||||||
|
}
|
||||||
|
for (unsigned i = s; i < _s.size(); i += 2)
|
||||||
|
{
|
||||||
|
int h = fromHex(_s[i], WhenError::DontThrow);
|
||||||
|
int l = fromHex(_s[i + 1], WhenError::DontThrow);
|
||||||
|
if (h != -1 && l != -1)
|
||||||
|
ret.push_back((byte)(h * 16 + l));
|
||||||
|
else if (_throw == WhenError::Throw)
|
||||||
|
BOOST_THROW_EXCEPTION(BadHexCharacter());
|
||||||
|
else
|
||||||
|
return bytes();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
182
libdevcore/CommonData.h
Normal file
182
libdevcore/CommonData.h
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file CommonData.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*
|
||||||
|
* Shared algorithms and data types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
// String conversion functions, mainly to/from hex/nibble/byte representations.
|
||||||
|
|
||||||
|
enum class WhenError
|
||||||
|
{
|
||||||
|
DontThrow = 0,
|
||||||
|
Throw = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class HexPrefix
|
||||||
|
{
|
||||||
|
DontAdd = 0,
|
||||||
|
Add = 1,
|
||||||
|
};
|
||||||
|
/// Convert a series of bytes to the corresponding string of hex duplets.
|
||||||
|
/// @param _w specifies the width of the first of the elements. Defaults to two - enough to represent a byte.
|
||||||
|
/// @example toHex("A\x69") == "4169"
|
||||||
|
template <class T>
|
||||||
|
std::string toHex(T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd)
|
||||||
|
{
|
||||||
|
std::ostringstream ret;
|
||||||
|
unsigned ii = 0;
|
||||||
|
for (auto i: _data)
|
||||||
|
ret << std::hex << std::setfill('0') << std::setw(ii++ ? 2 : _w) << (int)(typename std::make_unsigned<decltype(i)>::type)i;
|
||||||
|
return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a (printable) ASCII hex character into the correspnding integer value.
|
||||||
|
/// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5
|
||||||
|
int fromHex(char _i, WhenError _throw);
|
||||||
|
|
||||||
|
/// Converts a (printable) ASCII hex string into the corresponding byte stream.
|
||||||
|
/// @example fromHex("41626261") == asBytes("Abba")
|
||||||
|
/// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception.
|
||||||
|
bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow);
|
||||||
|
/// Converts byte array to a string containing the same (binary) data. Unless
|
||||||
|
/// the byte array happens to contain ASCII data, this won't be printable.
|
||||||
|
inline std::string asString(bytes const& _b)
|
||||||
|
{
|
||||||
|
return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts byte array ref to a string containing the same (binary) data. Unless
|
||||||
|
/// the byte array happens to contain ASCII data, this won't be printable.
|
||||||
|
inline std::string asString(bytesConstRef _b)
|
||||||
|
{
|
||||||
|
return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a string to a byte array containing the string's (byte) data.
|
||||||
|
inline bytes asBytes(std::string const& _b)
|
||||||
|
{
|
||||||
|
return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Big-endian to/from host endian conversion functions.
|
||||||
|
|
||||||
|
/// Converts a templated integer value to the big-endian byte-stream represented on a templated collection.
|
||||||
|
/// The size of the collection object will be unchanged. If it is too small, it will not represent the
|
||||||
|
/// value properly, if too big then the additional elements will be zeroed out.
|
||||||
|
/// @a Out will typically be either std::string or bytes.
|
||||||
|
/// @a T will typically by unsigned, u160, u256 or bigint.
|
||||||
|
template <class T, class Out>
|
||||||
|
inline void toBigEndian(T _val, Out& o_out)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
|
||||||
|
for (auto i = o_out.size(); i != 0; _val >>= 8, i--)
|
||||||
|
{
|
||||||
|
T v = _val & (T)0xff;
|
||||||
|
o_out[i - 1] = (typename Out::value_type)(uint8_t)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a big-endian byte-stream represented on a templated collection to a templated integer value.
|
||||||
|
/// @a _In will typically be either std::string or bytes.
|
||||||
|
/// @a T will typically by unsigned, u160, u256 or bigint.
|
||||||
|
template <class T, class _In>
|
||||||
|
inline T fromBigEndian(_In const& _bytes)
|
||||||
|
{
|
||||||
|
T ret = (T)0;
|
||||||
|
for (auto i: _bytes)
|
||||||
|
ret = (T)((ret << 8) | (byte)(typename std::make_unsigned<typename _In::value_type>::type)i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }
|
||||||
|
inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); return ret; }
|
||||||
|
|
||||||
|
/// Convenience function for toBigEndian.
|
||||||
|
/// @returns a byte array just big enough to represent @a _val.
|
||||||
|
template <class T>
|
||||||
|
inline bytes toCompactBigEndian(T _val, unsigned _min = 0)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
|
||||||
|
int i = 0;
|
||||||
|
for (T v = _val; v; ++i, v >>= 8) {}
|
||||||
|
bytes ret(std::max<unsigned>(_min, i), 0);
|
||||||
|
toBigEndian(_val, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
inline bytes toCompactBigEndian(byte _val, unsigned _min = 0)
|
||||||
|
{
|
||||||
|
return (_min || _val) ? bytes{ _val } : bytes{};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience function for conversion of a u256 to hex
|
||||||
|
inline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd)
|
||||||
|
{
|
||||||
|
std::string str = toHex(toBigEndian(val));
|
||||||
|
return (prefix == HexPrefix::Add) ? "0x" + str : str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Algorithms for string and string-like collections.
|
||||||
|
|
||||||
|
/// Escapes a string into the C-string representation.
|
||||||
|
/// @p _all if true will escape all characters, not just the unprintable ones.
|
||||||
|
std::string escaped(std::string const& _s, bool _all = true);
|
||||||
|
/// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero.
|
||||||
|
template <class T>
|
||||||
|
inline unsigned bytesRequired(T _i)
|
||||||
|
{
|
||||||
|
static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
|
||||||
|
unsigned i = 0;
|
||||||
|
for (; _i != 0; ++i, _i >>= 8) {}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
/// Concatenate the contents of a container onto a vector
|
||||||
|
template <class T, class U> std::vector<T>& operator+=(std::vector<T>& _a, U const& _b)
|
||||||
|
{
|
||||||
|
for (auto const& i: _b)
|
||||||
|
_a.push_back(i);
|
||||||
|
return _a;
|
||||||
|
}
|
||||||
|
/// Concatenate two vectors of elements.
|
||||||
|
template <class T>
|
||||||
|
inline std::vector<T> operator+(std::vector<T> const& _a, std::vector<T> const& _b)
|
||||||
|
{
|
||||||
|
std::vector<T> ret(_a);
|
||||||
|
return ret += _b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class V>
|
||||||
|
bool contains(T const& _t, V const& _v)
|
||||||
|
{
|
||||||
|
return std::end(_t) != std::find(std::begin(_t), std::end(_t), _v);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
90
libdevcore/CommonIO.cpp
Normal file
90
libdevcore/CommonIO.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file CommonIO.cpp
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CommonIO.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <termios.h>
|
||||||
|
#endif
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include "Exceptions.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename _T>
|
||||||
|
inline _T contentsGeneric(std::string const& _file)
|
||||||
|
{
|
||||||
|
_T ret;
|
||||||
|
size_t const c_elementSize = sizeof(typename _T::value_type);
|
||||||
|
std::ifstream is(_file, std::ifstream::binary);
|
||||||
|
if (!is)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// get length of file:
|
||||||
|
is.seekg(0, is.end);
|
||||||
|
streamoff length = is.tellg();
|
||||||
|
if (length == 0)
|
||||||
|
return ret; // do not read empty file (MSVC does not like it)
|
||||||
|
is.seekg(0, is.beg);
|
||||||
|
|
||||||
|
ret.resize((length + c_elementSize - 1) / c_elementSize);
|
||||||
|
is.read(const_cast<char*>(reinterpret_cast<char const*>(ret.data())), length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
string dev::contentsString(string const& _file)
|
||||||
|
{
|
||||||
|
return contentsGeneric<string>(_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dev::writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename)
|
||||||
|
{
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
if (_writeDeleteRename)
|
||||||
|
{
|
||||||
|
fs::path tempPath = fs::unique_path(_file + "-%%%%%%");
|
||||||
|
writeFile(tempPath.string(), _data, false);
|
||||||
|
// will delete _file if it exists
|
||||||
|
fs::rename(tempPath, _file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create directory if not existent
|
||||||
|
fs::path p(_file);
|
||||||
|
if (!fs::exists(p.parent_path()))
|
||||||
|
{
|
||||||
|
fs::create_directories(p.parent_path());
|
||||||
|
DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all));
|
||||||
|
}
|
||||||
|
|
||||||
|
ofstream s(_file, ios::trunc | ios::binary);
|
||||||
|
s.write(reinterpret_cast<char const*>(_data.data()), _data.size());
|
||||||
|
if (!s)
|
||||||
|
BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _file));
|
||||||
|
DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write));
|
||||||
|
}
|
||||||
|
}
|
54
libdevcore/CommonIO.h
Normal file
54
libdevcore/CommonIO.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file CommonIO.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*
|
||||||
|
* File & stream I/O routines.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Retrieve and returns the contents of the given file as a std::string.
|
||||||
|
/// If the file doesn't exist or isn't readable, returns an empty container / bytes.
|
||||||
|
std::string contentsString(std::string const& _file);
|
||||||
|
|
||||||
|
/// Write the given binary data into the given file, replacing the file if it pre-exists.
|
||||||
|
/// Throws exception on error.
|
||||||
|
/// @param _writeDeleteRename useful not to lose any data: If set, first writes to another file in
|
||||||
|
/// the same directory and then moves that file.
|
||||||
|
void writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename = false);
|
||||||
|
/// Write the given binary data into the given file, replacing the file if it pre-exists.
|
||||||
|
inline void writeFile(std::string const& _file, bytes const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(&_data), _writeDeleteRename); }
|
||||||
|
inline void writeFile(std::string const& _file, std::string const& _data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(_data), _writeDeleteRename); }
|
||||||
|
/// Converts arbitrary value to string representation using std::stringstream.
|
||||||
|
template <class _T>
|
||||||
|
std::string toString(_T const& _t)
|
||||||
|
{
|
||||||
|
std::ostringstream o;
|
||||||
|
o << _t;
|
||||||
|
return o.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
87
libdevcore/Exceptions.h
Normal file
87
libdevcore/Exceptions.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file Exceptions.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
#include <boost/exception/exception.hpp>
|
||||||
|
#include <boost/exception/info.hpp>
|
||||||
|
#include <boost/exception/info_tuple.hpp>
|
||||||
|
#include <boost/exception/diagnostic_information.hpp>
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include "CommonData.h"
|
||||||
|
#include "FixedHash.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Base class for all exceptions.
|
||||||
|
struct Exception: virtual std::exception, virtual boost::exception
|
||||||
|
{
|
||||||
|
Exception(std::string _message = std::string()): m_message(std::move(_message)) {}
|
||||||
|
const char* what() const noexcept override { return m_message.empty() ? std::exception::what() : m_message.c_str(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEV_SIMPLE_EXCEPTION(X) struct X: virtual Exception { const char* what() const noexcept override { return #X; } }
|
||||||
|
|
||||||
|
/// Base class for all RLP exceptions.
|
||||||
|
struct RLPException: virtual Exception { RLPException(std::string _message = std::string()): Exception(_message) {} };
|
||||||
|
#define DEV_SIMPLE_EXCEPTION_RLP(X) struct X: virtual RLPException { const char* what() const noexcept override { return #X; } }
|
||||||
|
|
||||||
|
DEV_SIMPLE_EXCEPTION_RLP(BadCast);
|
||||||
|
DEV_SIMPLE_EXCEPTION_RLP(BadRLP);
|
||||||
|
DEV_SIMPLE_EXCEPTION_RLP(OversizeRLP);
|
||||||
|
DEV_SIMPLE_EXCEPTION_RLP(UndersizeRLP);
|
||||||
|
|
||||||
|
DEV_SIMPLE_EXCEPTION(BadHexCharacter);
|
||||||
|
DEV_SIMPLE_EXCEPTION(NoNetworking);
|
||||||
|
DEV_SIMPLE_EXCEPTION(NoUPnPDevice);
|
||||||
|
DEV_SIMPLE_EXCEPTION(RootNotFound);
|
||||||
|
struct BadRoot: virtual Exception { public: BadRoot(h256 const& _root): Exception("BadRoot " + _root.hex()), root(_root) {} h256 root; };
|
||||||
|
DEV_SIMPLE_EXCEPTION(FileError);
|
||||||
|
DEV_SIMPLE_EXCEPTION(Overflow);
|
||||||
|
DEV_SIMPLE_EXCEPTION(FailedInvariant);
|
||||||
|
DEV_SIMPLE_EXCEPTION(ValueTooLarge);
|
||||||
|
|
||||||
|
struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} };
|
||||||
|
struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} };
|
||||||
|
|
||||||
|
// error information to be added to exceptions
|
||||||
|
using errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>;
|
||||||
|
using errinfo_wrongAddress = boost::error_info<struct tag_address, std::string>;
|
||||||
|
using errinfo_comment = boost::error_info<struct tag_comment, std::string>;
|
||||||
|
using errinfo_required = boost::error_info<struct tag_required, bigint>;
|
||||||
|
using errinfo_got = boost::error_info<struct tag_got, bigint>;
|
||||||
|
using errinfo_min = boost::error_info<struct tag_min, bigint>;
|
||||||
|
using errinfo_max = boost::error_info<struct tag_max, bigint>;
|
||||||
|
using RequirementError = boost::tuple<errinfo_required, errinfo_got>;
|
||||||
|
using errinfo_hash256 = boost::error_info<struct tag_hash, h256>;
|
||||||
|
using errinfo_required_h256 = boost::error_info<struct tag_required_h256, h256>;
|
||||||
|
using errinfo_got_h256 = boost::error_info<struct tag_get_h256, h256>;
|
||||||
|
using Hash256RequirementError = boost::tuple<errinfo_required_h256, errinfo_got_h256>;
|
||||||
|
using errinfo_extraData = boost::error_info<struct tag_extraData, bytes>;
|
||||||
|
|
||||||
|
}
|
50
libdevcore/FixedHash.cpp
Normal file
50
libdevcore/FixedHash.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file FixedHash.cpp
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FixedHash.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
boost::random_device dev::s_fixedHashEngine;
|
||||||
|
|
||||||
|
h128 dev::fromUUID(std::string const& _uuid)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return h128(boost::replace_all_copy(_uuid, "-", ""));
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return h128();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string dev::toUUID(h128 const& _uuid)
|
||||||
|
{
|
||||||
|
std::string ret = toHex(_uuid.ref());
|
||||||
|
for (unsigned i: {20, 16, 12, 8})
|
||||||
|
ret.insert(ret.begin() + i, '-');
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
306
libdevcore/FixedHash.h
Normal file
306
libdevcore/FixedHash.h
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file FixedHash.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*
|
||||||
|
* The FixedHash fixed-size "hash" container type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <boost/random/random_device.hpp>
|
||||||
|
#include <boost/random/uniform_int_distribution.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include "CommonData.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Compile-time calculation of Log2 of constant values.
|
||||||
|
template <unsigned N> struct StaticLog2 { enum { result = 1 + StaticLog2<N/2>::result }; };
|
||||||
|
template <> struct StaticLog2<1> { enum { result = 0 }; };
|
||||||
|
|
||||||
|
extern boost::random_device s_fixedHashEngine;
|
||||||
|
|
||||||
|
/// Fixed-size raw-byte array container type, with an API optimised for storing hashes.
|
||||||
|
/// Transparently converts to/from the corresponding arithmetic type; this will
|
||||||
|
/// assume the data contained in the hash is big-endian.
|
||||||
|
template <unsigned N>
|
||||||
|
class FixedHash
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The corresponding arithmetic type.
|
||||||
|
using Arith = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
|
||||||
|
|
||||||
|
/// The size of the container.
|
||||||
|
enum { size = N };
|
||||||
|
|
||||||
|
/// A dummy flag to avoid accidental construction from pointer.
|
||||||
|
enum ConstructFromPointerType { ConstructFromPointer };
|
||||||
|
|
||||||
|
/// Method to convert from a string.
|
||||||
|
enum ConstructFromStringType { FromHex, FromBinary };
|
||||||
|
|
||||||
|
/// Method to convert from a string.
|
||||||
|
enum ConstructFromHashType { AlignLeft, AlignRight, FailIfDifferent };
|
||||||
|
|
||||||
|
/// Construct an empty hash.
|
||||||
|
FixedHash() { m_data.fill(0); }
|
||||||
|
|
||||||
|
/// Construct from another hash, filling with zeroes or cropping as necessary.
|
||||||
|
template <unsigned M> explicit FixedHash(FixedHash<M> const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; }
|
||||||
|
|
||||||
|
/// Convert from the corresponding arithmetic type.
|
||||||
|
FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
|
||||||
|
|
||||||
|
/// Convert from unsigned
|
||||||
|
explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); }
|
||||||
|
|
||||||
|
/// Explicitly construct, copying from a byte array.
|
||||||
|
explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
|
||||||
|
|
||||||
|
/// Explicitly construct, copying from a byte array.
|
||||||
|
explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min<unsigned>(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } }
|
||||||
|
|
||||||
|
/// Explicitly construct, copying from a bytes in memory with given pointer.
|
||||||
|
explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }
|
||||||
|
|
||||||
|
/// Explicitly construct, copying from a string.
|
||||||
|
explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht) {}
|
||||||
|
|
||||||
|
/// Convert to arithmetic type.
|
||||||
|
operator Arith() const { return fromBigEndian<Arith>(m_data); }
|
||||||
|
|
||||||
|
/// @returns true iff this is the empty hash.
|
||||||
|
explicit operator bool() const { return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; }); }
|
||||||
|
|
||||||
|
// The obvious comparison operators.
|
||||||
|
bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }
|
||||||
|
bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }
|
||||||
|
bool operator<(FixedHash const& _c) const { for (unsigned i = 0; i < N; ++i) if (m_data[i] < _c.m_data[i]) return true; else if (m_data[i] > _c.m_data[i]) return false; return false; }
|
||||||
|
bool operator>=(FixedHash const& _c) const { return !operator<(_c); }
|
||||||
|
bool operator<=(FixedHash const& _c) const { return operator==(_c) || operator<(_c); }
|
||||||
|
bool operator>(FixedHash const& _c) const { return !operator<=(_c); }
|
||||||
|
|
||||||
|
// The obvious binary operators.
|
||||||
|
FixedHash& operator^=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] ^= _c.m_data[i]; return *this; }
|
||||||
|
FixedHash operator^(FixedHash const& _c) const { return FixedHash(*this) ^= _c; }
|
||||||
|
FixedHash& operator|=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] |= _c.m_data[i]; return *this; }
|
||||||
|
FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; }
|
||||||
|
FixedHash& operator&=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; }
|
||||||
|
FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
|
||||||
|
FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; }
|
||||||
|
|
||||||
|
// Big-endian increment.
|
||||||
|
FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {} return *this; }
|
||||||
|
|
||||||
|
/// @returns true if all one-bits in @a _c are set in this object.
|
||||||
|
bool contains(FixedHash const& _c) const { return (*this & _c) == _c; }
|
||||||
|
|
||||||
|
/// @returns a particular byte from the hash.
|
||||||
|
byte& operator[](unsigned _i) { return m_data[_i]; }
|
||||||
|
/// @returns a particular byte from the hash.
|
||||||
|
byte operator[](unsigned _i) const { return m_data[_i]; }
|
||||||
|
|
||||||
|
/// @returns an abridged version of the hash as a user-readable hex string.
|
||||||
|
std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; }
|
||||||
|
|
||||||
|
/// @returns a version of the hash as a user-readable hex string that leaves out the middle part.
|
||||||
|
std::string abridgedMiddle() const { return toHex(ref().cropped(0, 4)) + "\342\200\246" + toHex(ref().cropped(N - 4)); }
|
||||||
|
|
||||||
|
/// @returns the hash as a user-readable hex string.
|
||||||
|
std::string hex() const { return toHex(ref()); }
|
||||||
|
|
||||||
|
/// @returns a mutable byte vector_ref to the object's data.
|
||||||
|
bytesRef ref() { return bytesRef(m_data.data(), N); }
|
||||||
|
|
||||||
|
/// @returns a constant byte vector_ref to the object's data.
|
||||||
|
bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }
|
||||||
|
|
||||||
|
/// @returns a mutable byte pointer to the object's data.
|
||||||
|
byte* data() { return m_data.data(); }
|
||||||
|
|
||||||
|
/// @returns a constant byte pointer to the object's data.
|
||||||
|
byte const* data() const { return m_data.data(); }
|
||||||
|
|
||||||
|
/// @returns a copy of the object's data as a byte vector.
|
||||||
|
bytes asBytes() const { return bytes(data(), data() + N); }
|
||||||
|
|
||||||
|
/// @returns a mutable reference to the object's data as an STL array.
|
||||||
|
std::array<byte, N>& asArray() { return m_data; }
|
||||||
|
|
||||||
|
/// @returns a constant reference to the object's data as an STL array.
|
||||||
|
std::array<byte, N> const& asArray() const { return m_data; }
|
||||||
|
|
||||||
|
/// Populate with random data.
|
||||||
|
template <class Engine>
|
||||||
|
void randomize(Engine& _eng)
|
||||||
|
{
|
||||||
|
for (auto& i: m_data)
|
||||||
|
i = (uint8_t)boost::random::uniform_int_distribution<uint16_t>(0, 255)(_eng);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @returns a random valued object.
|
||||||
|
static FixedHash random() { FixedHash ret; ret.randomize(s_fixedHashEngine); return ret; }
|
||||||
|
|
||||||
|
struct hash
|
||||||
|
{
|
||||||
|
/// Make a hash of the object's data.
|
||||||
|
size_t operator()(FixedHash const& _value) const { return boost::hash_range(_value.m_data.cbegin(), _value.m_data.cend()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <unsigned P, unsigned M> inline FixedHash& shiftBloom(FixedHash<M> const& _h)
|
||||||
|
{
|
||||||
|
return (*this |= _h.template bloomPart<P, N>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned P, unsigned M> inline bool containsBloom(FixedHash<M> const& _h)
|
||||||
|
{
|
||||||
|
return contains(_h.template bloomPart<P, N>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <unsigned P, unsigned M> inline FixedHash<M> bloomPart() const
|
||||||
|
{
|
||||||
|
unsigned const c_bloomBits = M * 8;
|
||||||
|
unsigned const c_mask = c_bloomBits - 1;
|
||||||
|
unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8;
|
||||||
|
|
||||||
|
static_assert((M & (M - 1)) == 0, "M must be power-of-two");
|
||||||
|
static_assert(P * c_bloomBytes <= N, "out of range");
|
||||||
|
|
||||||
|
FixedHash<M> ret;
|
||||||
|
byte const* p = data();
|
||||||
|
for (unsigned i = 0; i < P; ++i)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
for (unsigned j = 0; j < c_bloomBytes; ++j, ++p)
|
||||||
|
index = (index << 8) | *p;
|
||||||
|
index &= c_mask;
|
||||||
|
ret[M - 1 - index / 8] |= (1 << (index % 8));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the index of the first bit set to one, or size() * 8 if no bits are set.
|
||||||
|
inline unsigned firstBitSet() const
|
||||||
|
{
|
||||||
|
unsigned ret = 0;
|
||||||
|
for (auto d: m_data)
|
||||||
|
if (d)
|
||||||
|
for (;; ++ret, d <<= 1)
|
||||||
|
if (d & 0x80)
|
||||||
|
return ret;
|
||||||
|
else {}
|
||||||
|
else
|
||||||
|
ret += 8;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() { m_data.fill(0); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<byte, N> m_data; ///< The binary data.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Fast equality operator for h256.
|
||||||
|
template<> inline bool FixedHash<32>::operator==(FixedHash<32> const& _other) const
|
||||||
|
{
|
||||||
|
const uint64_t* hash1 = (const uint64_t*)data();
|
||||||
|
const uint64_t* hash2 = (const uint64_t*)_other.data();
|
||||||
|
return (hash1[0] == hash2[0]) && (hash1[1] == hash2[1]) && (hash1[2] == hash2[2]) && (hash1[3] == hash2[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fast std::hash compatible hash function object for h256.
|
||||||
|
template<> inline size_t FixedHash<32>::hash::operator()(FixedHash<32> const& value) const
|
||||||
|
{
|
||||||
|
uint64_t const* data = reinterpret_cast<uint64_t const*>(value.data());
|
||||||
|
return boost::hash_range(data, data + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stream I/O for the FixedHash class.
|
||||||
|
template <unsigned N>
|
||||||
|
inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
|
||||||
|
{
|
||||||
|
_out << std::noshowbase << std::hex << std::setfill('0');
|
||||||
|
for (unsigned i = 0; i < N; ++i)
|
||||||
|
_out << std::setw(2) << (int)_h[i];
|
||||||
|
_out << std::dec;
|
||||||
|
return _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Common types of FixedHash.
|
||||||
|
using h2048 = FixedHash<256>;
|
||||||
|
using h1024 = FixedHash<128>;
|
||||||
|
using h520 = FixedHash<65>;
|
||||||
|
using h512 = FixedHash<64>;
|
||||||
|
using h256 = FixedHash<32>;
|
||||||
|
using h160 = FixedHash<20>;
|
||||||
|
using h128 = FixedHash<16>;
|
||||||
|
using h64 = FixedHash<8>;
|
||||||
|
using h512s = std::vector<h512>;
|
||||||
|
using h256s = std::vector<h256>;
|
||||||
|
using h160s = std::vector<h160>;
|
||||||
|
using h256Set = std::set<h256>;
|
||||||
|
using h160Set = std::set<h160>;
|
||||||
|
using h256Hash = std::unordered_set<h256>;
|
||||||
|
using h160Hash = std::unordered_set<h160>;
|
||||||
|
|
||||||
|
/// Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
|
||||||
|
inline h160 right160(h256 const& _t)
|
||||||
|
{
|
||||||
|
h160 ret;
|
||||||
|
memcpy(ret.data(), _t.data() + 12, 20);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert the given value into h160 (160-bit unsigned integer) using the left 20 bytes.
|
||||||
|
inline h160 left160(h256 const& _t)
|
||||||
|
{
|
||||||
|
h160 ret;
|
||||||
|
memcpy(&ret[0], _t.data(), 20);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
h128 fromUUID(std::string const& _uuid);
|
||||||
|
|
||||||
|
std::string toUUID(h128 const& _uuid);
|
||||||
|
|
||||||
|
inline std::string toString(h256s const& _bs)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "[ ";
|
||||||
|
for (auto i: _bs)
|
||||||
|
out << i.abridged() << ", ";
|
||||||
|
out << "]";
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
/// Forward std::hash<dev::FixedHash> to dev::FixedHash::hash.
|
||||||
|
template<> struct hash<dev::h64>: dev::h64::hash {};
|
||||||
|
template<> struct hash<dev::h128>: dev::h128::hash {};
|
||||||
|
template<> struct hash<dev::h160>: dev::h160::hash {};
|
||||||
|
template<> struct hash<dev::h256>: dev::h256::hash {};
|
||||||
|
template<> struct hash<dev::h512>: dev::h512::hash {};
|
||||||
|
}
|
440
libdevcore/Hash.cpp
Normal file
440
libdevcore/Hash.cpp
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file Hash.cpp
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Hash.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include "picosha2.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
h256 sha256(bytesConstRef _input)
|
||||||
|
{
|
||||||
|
h256 ret;
|
||||||
|
picosha2::hash256(_input.begin(), _input.end(), ret.data(), ret.data() + 32);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace rmd160
|
||||||
|
{
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
*
|
||||||
|
* FILE: rmd160.h
|
||||||
|
* FILE: rmd160.c
|
||||||
|
*
|
||||||
|
* CONTENTS: Header file for a sample C-implementation of the
|
||||||
|
* RIPEMD-160 hash-function.
|
||||||
|
* TARGET: any computer with an ANSI C compiler
|
||||||
|
*
|
||||||
|
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
|
||||||
|
* DATE: 1 March 1996
|
||||||
|
* VERSION: 1.0
|
||||||
|
*
|
||||||
|
* Copyright (c) Katholieke Universiteit Leuven
|
||||||
|
* 1996, All Rights Reserved
|
||||||
|
*
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
// Adapted into "header-only" format by Gav Wood.
|
||||||
|
|
||||||
|
/* macro definitions */
|
||||||
|
|
||||||
|
#define RMDsize 160
|
||||||
|
|
||||||
|
/* collect four bytes into one word: */
|
||||||
|
#define BYTES_TO_DWORD(strptr) \
|
||||||
|
(((uint32_t) *((strptr)+3) << 24) | \
|
||||||
|
((uint32_t) *((strptr)+2) << 16) | \
|
||||||
|
((uint32_t) *((strptr)+1) << 8) | \
|
||||||
|
((uint32_t) *(strptr)))
|
||||||
|
|
||||||
|
/* ROL(x, n) cyclically rotates x over n bits to the left */
|
||||||
|
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
|
||||||
|
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
/* the five basic functions F(), G() and H() */
|
||||||
|
#define F(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||||
|
#define H(x, y, z) (((x) | ~(y)) ^ (z))
|
||||||
|
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||||
|
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
|
||||||
|
|
||||||
|
/* the ten basic operations FF() through III() */
|
||||||
|
#define FF(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F((b), (c), (d)) + (x);\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define GG(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define HH(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define II(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define JJ(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FFF(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F((b), (c), (d)) + (x);\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define GGG(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define HHH(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define III(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define JJJ(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDinit(uint32_t *MDbuf)
|
||||||
|
{
|
||||||
|
MDbuf[0] = 0x67452301UL;
|
||||||
|
MDbuf[1] = 0xefcdab89UL;
|
||||||
|
MDbuf[2] = 0x98badcfeUL;
|
||||||
|
MDbuf[3] = 0x10325476UL;
|
||||||
|
MDbuf[4] = 0xc3d2e1f0UL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
void MDcompress(uint32_t *MDbuf, uint32_t *X)
|
||||||
|
{
|
||||||
|
uint32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
|
||||||
|
dd = MDbuf[3], ee = MDbuf[4];
|
||||||
|
uint32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
|
||||||
|
ddd = MDbuf[3], eee = MDbuf[4];
|
||||||
|
|
||||||
|
/* round 1 */
|
||||||
|
FF(aa, bb, cc, dd, ee, X[ 0], 11);
|
||||||
|
FF(ee, aa, bb, cc, dd, X[ 1], 14);
|
||||||
|
FF(dd, ee, aa, bb, cc, X[ 2], 15);
|
||||||
|
FF(cc, dd, ee, aa, bb, X[ 3], 12);
|
||||||
|
FF(bb, cc, dd, ee, aa, X[ 4], 5);
|
||||||
|
FF(aa, bb, cc, dd, ee, X[ 5], 8);
|
||||||
|
FF(ee, aa, bb, cc, dd, X[ 6], 7);
|
||||||
|
FF(dd, ee, aa, bb, cc, X[ 7], 9);
|
||||||
|
FF(cc, dd, ee, aa, bb, X[ 8], 11);
|
||||||
|
FF(bb, cc, dd, ee, aa, X[ 9], 13);
|
||||||
|
FF(aa, bb, cc, dd, ee, X[10], 14);
|
||||||
|
FF(ee, aa, bb, cc, dd, X[11], 15);
|
||||||
|
FF(dd, ee, aa, bb, cc, X[12], 6);
|
||||||
|
FF(cc, dd, ee, aa, bb, X[13], 7);
|
||||||
|
FF(bb, cc, dd, ee, aa, X[14], 9);
|
||||||
|
FF(aa, bb, cc, dd, ee, X[15], 8);
|
||||||
|
|
||||||
|
/* round 2 */
|
||||||
|
GG(ee, aa, bb, cc, dd, X[ 7], 7);
|
||||||
|
GG(dd, ee, aa, bb, cc, X[ 4], 6);
|
||||||
|
GG(cc, dd, ee, aa, bb, X[13], 8);
|
||||||
|
GG(bb, cc, dd, ee, aa, X[ 1], 13);
|
||||||
|
GG(aa, bb, cc, dd, ee, X[10], 11);
|
||||||
|
GG(ee, aa, bb, cc, dd, X[ 6], 9);
|
||||||
|
GG(dd, ee, aa, bb, cc, X[15], 7);
|
||||||
|
GG(cc, dd, ee, aa, bb, X[ 3], 15);
|
||||||
|
GG(bb, cc, dd, ee, aa, X[12], 7);
|
||||||
|
GG(aa, bb, cc, dd, ee, X[ 0], 12);
|
||||||
|
GG(ee, aa, bb, cc, dd, X[ 9], 15);
|
||||||
|
GG(dd, ee, aa, bb, cc, X[ 5], 9);
|
||||||
|
GG(cc, dd, ee, aa, bb, X[ 2], 11);
|
||||||
|
GG(bb, cc, dd, ee, aa, X[14], 7);
|
||||||
|
GG(aa, bb, cc, dd, ee, X[11], 13);
|
||||||
|
GG(ee, aa, bb, cc, dd, X[ 8], 12);
|
||||||
|
|
||||||
|
/* round 3 */
|
||||||
|
HH(dd, ee, aa, bb, cc, X[ 3], 11);
|
||||||
|
HH(cc, dd, ee, aa, bb, X[10], 13);
|
||||||
|
HH(bb, cc, dd, ee, aa, X[14], 6);
|
||||||
|
HH(aa, bb, cc, dd, ee, X[ 4], 7);
|
||||||
|
HH(ee, aa, bb, cc, dd, X[ 9], 14);
|
||||||
|
HH(dd, ee, aa, bb, cc, X[15], 9);
|
||||||
|
HH(cc, dd, ee, aa, bb, X[ 8], 13);
|
||||||
|
HH(bb, cc, dd, ee, aa, X[ 1], 15);
|
||||||
|
HH(aa, bb, cc, dd, ee, X[ 2], 14);
|
||||||
|
HH(ee, aa, bb, cc, dd, X[ 7], 8);
|
||||||
|
HH(dd, ee, aa, bb, cc, X[ 0], 13);
|
||||||
|
HH(cc, dd, ee, aa, bb, X[ 6], 6);
|
||||||
|
HH(bb, cc, dd, ee, aa, X[13], 5);
|
||||||
|
HH(aa, bb, cc, dd, ee, X[11], 12);
|
||||||
|
HH(ee, aa, bb, cc, dd, X[ 5], 7);
|
||||||
|
HH(dd, ee, aa, bb, cc, X[12], 5);
|
||||||
|
|
||||||
|
/* round 4 */
|
||||||
|
II(cc, dd, ee, aa, bb, X[ 1], 11);
|
||||||
|
II(bb, cc, dd, ee, aa, X[ 9], 12);
|
||||||
|
II(aa, bb, cc, dd, ee, X[11], 14);
|
||||||
|
II(ee, aa, bb, cc, dd, X[10], 15);
|
||||||
|
II(dd, ee, aa, bb, cc, X[ 0], 14);
|
||||||
|
II(cc, dd, ee, aa, bb, X[ 8], 15);
|
||||||
|
II(bb, cc, dd, ee, aa, X[12], 9);
|
||||||
|
II(aa, bb, cc, dd, ee, X[ 4], 8);
|
||||||
|
II(ee, aa, bb, cc, dd, X[13], 9);
|
||||||
|
II(dd, ee, aa, bb, cc, X[ 3], 14);
|
||||||
|
II(cc, dd, ee, aa, bb, X[ 7], 5);
|
||||||
|
II(bb, cc, dd, ee, aa, X[15], 6);
|
||||||
|
II(aa, bb, cc, dd, ee, X[14], 8);
|
||||||
|
II(ee, aa, bb, cc, dd, X[ 5], 6);
|
||||||
|
II(dd, ee, aa, bb, cc, X[ 6], 5);
|
||||||
|
II(cc, dd, ee, aa, bb, X[ 2], 12);
|
||||||
|
|
||||||
|
/* round 5 */
|
||||||
|
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
|
||||||
|
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
|
||||||
|
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
|
||||||
|
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
|
||||||
|
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
|
||||||
|
JJ(bb, cc, dd, ee, aa, X[12], 8);
|
||||||
|
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
|
||||||
|
JJ(ee, aa, bb, cc, dd, X[10], 12);
|
||||||
|
JJ(dd, ee, aa, bb, cc, X[14], 5);
|
||||||
|
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
|
||||||
|
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
|
||||||
|
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
|
||||||
|
JJ(ee, aa, bb, cc, dd, X[11], 11);
|
||||||
|
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
|
||||||
|
JJ(cc, dd, ee, aa, bb, X[15], 5);
|
||||||
|
JJ(bb, cc, dd, ee, aa, X[13], 6);
|
||||||
|
|
||||||
|
/* parallel round 1 */
|
||||||
|
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
|
||||||
|
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
|
||||||
|
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
|
||||||
|
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
|
||||||
|
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
|
||||||
|
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
|
||||||
|
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
|
||||||
|
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
|
||||||
|
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
|
||||||
|
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
|
||||||
|
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
|
||||||
|
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
|
||||||
|
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
|
||||||
|
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
|
||||||
|
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
|
||||||
|
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
|
||||||
|
|
||||||
|
/* parallel round 2 */
|
||||||
|
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
|
||||||
|
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
|
||||||
|
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
|
||||||
|
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
|
||||||
|
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
|
||||||
|
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
|
||||||
|
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
|
||||||
|
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
|
||||||
|
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
|
||||||
|
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
|
||||||
|
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
|
||||||
|
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
|
||||||
|
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
|
||||||
|
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
|
||||||
|
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
|
||||||
|
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
|
||||||
|
|
||||||
|
/* parallel round 3 */
|
||||||
|
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
|
||||||
|
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
|
||||||
|
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
|
||||||
|
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
|
||||||
|
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
|
||||||
|
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
|
||||||
|
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
|
||||||
|
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
|
||||||
|
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
|
||||||
|
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
|
||||||
|
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
|
||||||
|
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
|
||||||
|
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
|
||||||
|
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
|
||||||
|
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
|
||||||
|
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
|
||||||
|
|
||||||
|
/* parallel round 4 */
|
||||||
|
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
|
||||||
|
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
|
||||||
|
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
|
||||||
|
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
|
||||||
|
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
|
||||||
|
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
|
||||||
|
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
|
||||||
|
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
|
||||||
|
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
|
||||||
|
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
|
||||||
|
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
|
||||||
|
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
|
||||||
|
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
|
||||||
|
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
|
||||||
|
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
|
||||||
|
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
|
||||||
|
|
||||||
|
/* parallel round 5 */
|
||||||
|
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
|
||||||
|
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
|
||||||
|
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
|
||||||
|
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
|
||||||
|
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
|
||||||
|
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
|
||||||
|
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
|
||||||
|
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
|
||||||
|
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
|
||||||
|
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
|
||||||
|
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
|
||||||
|
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
|
||||||
|
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
|
||||||
|
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
|
||||||
|
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
|
||||||
|
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
|
||||||
|
|
||||||
|
/* combine results */
|
||||||
|
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
|
||||||
|
MDbuf[1] = MDbuf[2] + dd + eee;
|
||||||
|
MDbuf[2] = MDbuf[3] + ee + aaa;
|
||||||
|
MDbuf[3] = MDbuf[4] + aa + bbb;
|
||||||
|
MDbuf[4] = MDbuf[0] + bb + ccc;
|
||||||
|
MDbuf[0] = ddd;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDfinish(uint32_t *MDbuf, byte const *strptr, uint32_t lswlen, uint32_t mswlen)
|
||||||
|
{
|
||||||
|
unsigned int i; /* counter */
|
||||||
|
uint32_t X[16]; /* message words */
|
||||||
|
|
||||||
|
memset(X, 0, 16*sizeof(uint32_t));
|
||||||
|
|
||||||
|
/* put bytes from strptr into X */
|
||||||
|
for (i=0; i<(lswlen&63); i++) {
|
||||||
|
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
|
||||||
|
X[i>>2] ^= (uint32_t) *strptr++ << (8 * (i&3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* append the bit m_n == 1 */
|
||||||
|
X[(lswlen>>2)&15] ^= (uint32_t)1 << (8*(lswlen&3) + 7);
|
||||||
|
|
||||||
|
if ((lswlen & 63) > 55) {
|
||||||
|
/* length goes to next block */
|
||||||
|
MDcompress(MDbuf, X);
|
||||||
|
memset(X, 0, 16*sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* append length in bits*/
|
||||||
|
X[14] = lswlen << 3;
|
||||||
|
X[15] = (lswlen >> 29) | (mswlen << 3);
|
||||||
|
MDcompress(MDbuf, X);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ROL
|
||||||
|
#undef F
|
||||||
|
#undef G
|
||||||
|
#undef H
|
||||||
|
#undef I
|
||||||
|
#undef J
|
||||||
|
#undef FF
|
||||||
|
#undef GG
|
||||||
|
#undef HH
|
||||||
|
#undef II
|
||||||
|
#undef JJ
|
||||||
|
#undef FFF
|
||||||
|
#undef GGG
|
||||||
|
#undef HHH
|
||||||
|
#undef III
|
||||||
|
#undef JJJ
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @returns RMD(_input)
|
||||||
|
*/
|
||||||
|
h160 ripemd160(bytesConstRef _input)
|
||||||
|
{
|
||||||
|
h160 hashcode;
|
||||||
|
uint32_t buffer[RMDsize / 32]; // contains (A, B, C, D(, E))
|
||||||
|
uint32_t current[16]; // current 16-word chunk
|
||||||
|
|
||||||
|
// initialize
|
||||||
|
rmd160::MDinit(buffer);
|
||||||
|
byte const* message = _input.data();
|
||||||
|
uint32_t remaining = _input.size(); // # of bytes not yet processed
|
||||||
|
|
||||||
|
// process message in 16x 4-byte chunks
|
||||||
|
for (; remaining >= 64; remaining -= 64)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
current[i] = BYTES_TO_DWORD(message);
|
||||||
|
message += 4;
|
||||||
|
}
|
||||||
|
rmd160::MDcompress(buffer, current);
|
||||||
|
}
|
||||||
|
// length mod 64 bytes left
|
||||||
|
|
||||||
|
// finish:
|
||||||
|
rmd160::MDfinish(buffer, message, _input.size(), 0);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < RMDsize / 8; i += 4)
|
||||||
|
{
|
||||||
|
hashcode[i] = buffer[i >> 2]; // implicit cast to byte
|
||||||
|
hashcode[i + 1] = (buffer[i >> 2] >> 8); //extracts the 8 least
|
||||||
|
hashcode[i + 2] = (buffer[i >> 2] >> 16); // significant bits.
|
||||||
|
hashcode[i + 3] = (buffer[i >> 2] >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef BYTES_TO_DWORD
|
||||||
|
#undef RMDsize
|
||||||
|
|
||||||
|
}
|
38
libdevcore/Hash.h
Normal file
38
libdevcore/Hash.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file Hash.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*
|
||||||
|
* The FixedHash fixed-size "hash" container type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "FixedHash.h"
|
||||||
|
#include "vector_ref.h"
|
||||||
|
#include "SHA3.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
h256 sha256(bytesConstRef _input);
|
||||||
|
|
||||||
|
h160 ripemd160(bytesConstRef _input);
|
||||||
|
|
||||||
|
}
|
223
libdevcore/SHA3.cpp
Normal file
223
libdevcore/SHA3.cpp
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file SHA3.cpp
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SHA3.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include "picosha2.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace keccak
|
||||||
|
{
|
||||||
|
|
||||||
|
/** libkeccak-tiny
|
||||||
|
*
|
||||||
|
* A single-file implementation of SHA-3 and SHAKE.
|
||||||
|
*
|
||||||
|
* Implementor: David Leon Gil
|
||||||
|
* License: CC0, attribution kindly requested. Blame taken too,
|
||||||
|
* but not liability.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define decshake(bits) \
|
||||||
|
int shake##bits(uint8_t*, size_t, const uint8_t*, size_t);
|
||||||
|
|
||||||
|
#define decsha3(bits) \
|
||||||
|
int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t);
|
||||||
|
|
||||||
|
decshake(128)
|
||||||
|
decshake(256)
|
||||||
|
decsha3(224)
|
||||||
|
decsha3(256)
|
||||||
|
decsha3(384)
|
||||||
|
decsha3(512)
|
||||||
|
|
||||||
|
/******** The Keccak-f[1600] permutation ********/
|
||||||
|
|
||||||
|
/*** Constants. ***/
|
||||||
|
static const uint8_t rho[24] = \
|
||||||
|
{ 1, 3, 6, 10, 15, 21,
|
||||||
|
28, 36, 45, 55, 2, 14,
|
||||||
|
27, 41, 56, 8, 25, 43,
|
||||||
|
62, 18, 39, 61, 20, 44};
|
||||||
|
static const uint8_t pi[24] = \
|
||||||
|
{10, 7, 11, 17, 18, 3,
|
||||||
|
5, 16, 8, 21, 24, 4,
|
||||||
|
15, 23, 19, 13, 12, 2,
|
||||||
|
20, 14, 22, 9, 6, 1};
|
||||||
|
static const uint64_t RC[24] = \
|
||||||
|
{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
|
||||||
|
0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
|
||||||
|
0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
|
||||||
|
0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
|
||||||
|
0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
|
||||||
|
0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
|
||||||
|
|
||||||
|
/*** Helper macros to unroll the permutation. ***/
|
||||||
|
#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
|
||||||
|
#define REPEAT6(e) e e e e e e
|
||||||
|
#define REPEAT24(e) REPEAT6(e e e e)
|
||||||
|
#define REPEAT5(e) e e e e e
|
||||||
|
#define FOR5(v, s, e) \
|
||||||
|
v = 0; \
|
||||||
|
REPEAT5(e; v += s;)
|
||||||
|
|
||||||
|
/*** Keccak-f[1600] ***/
|
||||||
|
static inline void keccakf(void* state) {
|
||||||
|
uint64_t* a = (uint64_t*)state;
|
||||||
|
uint64_t b[5] = {0};
|
||||||
|
uint64_t t = 0;
|
||||||
|
uint8_t x, y;
|
||||||
|
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
// Theta
|
||||||
|
FOR5(x, 1,
|
||||||
|
b[x] = 0;
|
||||||
|
FOR5(y, 5,
|
||||||
|
b[x] ^= a[x + y]; ))
|
||||||
|
FOR5(x, 1,
|
||||||
|
FOR5(y, 5,
|
||||||
|
a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
|
||||||
|
// Rho and pi
|
||||||
|
t = a[1];
|
||||||
|
x = 0;
|
||||||
|
REPEAT24(b[0] = a[pi[x]];
|
||||||
|
a[pi[x]] = rol(t, rho[x]);
|
||||||
|
t = b[0];
|
||||||
|
x++; )
|
||||||
|
// Chi
|
||||||
|
FOR5(y,
|
||||||
|
5,
|
||||||
|
FOR5(x, 1,
|
||||||
|
b[x] = a[y + x];)
|
||||||
|
FOR5(x, 1,
|
||||||
|
a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
|
||||||
|
// Iota
|
||||||
|
a[0] ^= RC[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******** The FIPS202-defined functions. ********/
|
||||||
|
|
||||||
|
/*** Some helper macros. ***/
|
||||||
|
|
||||||
|
#define _(S) do { S } while (0)
|
||||||
|
#define FOR(i, ST, L, S) \
|
||||||
|
_(for (size_t i = 0; i < L; i += ST) { S; })
|
||||||
|
#define mkapply_ds(NAME, S) \
|
||||||
|
static inline void NAME(uint8_t* dst, \
|
||||||
|
const uint8_t* src, \
|
||||||
|
size_t len) { \
|
||||||
|
FOR(i, 1, len, S); \
|
||||||
|
}
|
||||||
|
#define mkapply_sd(NAME, S) \
|
||||||
|
static inline void NAME(const uint8_t* src, \
|
||||||
|
uint8_t* dst, \
|
||||||
|
size_t len) { \
|
||||||
|
FOR(i, 1, len, S); \
|
||||||
|
}
|
||||||
|
|
||||||
|
mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
|
||||||
|
mkapply_sd(setout, dst[i] = src[i]) // setout
|
||||||
|
|
||||||
|
#define P keccakf
|
||||||
|
#define Plen 200
|
||||||
|
|
||||||
|
// Fold P*F over the full blocks of an input.
|
||||||
|
#define foldP(I, L, F) \
|
||||||
|
while (L >= rate) { \
|
||||||
|
F(a, I, rate); \
|
||||||
|
P(a); \
|
||||||
|
I += rate; \
|
||||||
|
L -= rate; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The sponge-based hash construction. **/
|
||||||
|
static inline int hash(uint8_t* out, size_t outlen,
|
||||||
|
const uint8_t* in, size_t inlen,
|
||||||
|
size_t rate, uint8_t delim) {
|
||||||
|
if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uint8_t a[Plen] = {0};
|
||||||
|
// Absorb input.
|
||||||
|
foldP(in, inlen, xorin);
|
||||||
|
// Xor in the DS and pad frame.
|
||||||
|
a[inlen] ^= delim;
|
||||||
|
a[rate - 1] ^= 0x80;
|
||||||
|
// Xor in the last block.
|
||||||
|
xorin(a, in, inlen);
|
||||||
|
// Apply P
|
||||||
|
P(a);
|
||||||
|
// Squeeze output.
|
||||||
|
foldP(out, outlen, setout);
|
||||||
|
setout(a, out, outlen);
|
||||||
|
memset(a, 0, 200);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Helper macros to define SHA3 and SHAKE instances. ***/
|
||||||
|
#define defshake(bits) \
|
||||||
|
int shake##bits(uint8_t* out, size_t outlen, \
|
||||||
|
const uint8_t* in, size_t inlen) { \
|
||||||
|
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
|
||||||
|
}
|
||||||
|
#define defsha3(bits) \
|
||||||
|
int sha3_##bits(uint8_t* out, size_t outlen, \
|
||||||
|
const uint8_t* in, size_t inlen) { \
|
||||||
|
if (outlen > (bits/8)) { \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** FIPS202 SHAKE VOFs ***/
|
||||||
|
defshake(128)
|
||||||
|
defshake(256)
|
||||||
|
|
||||||
|
/*** FIPS202 SHA3 FOFs ***/
|
||||||
|
defsha3(224)
|
||||||
|
defsha3(256)
|
||||||
|
defsha3(384)
|
||||||
|
defsha3(512)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned g_sha3Counter = 0;
|
||||||
|
|
||||||
|
bool sha3(bytesConstRef _input, bytesRef o_output)
|
||||||
|
{
|
||||||
|
// FIXME: What with unaligned memory?
|
||||||
|
if (o_output.size() != 32)
|
||||||
|
return false;
|
||||||
|
++g_sha3Counter;
|
||||||
|
keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size());
|
||||||
|
// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
59
libdevcore/SHA3.h
Normal file
59
libdevcore/SHA3.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file SHA3.h
|
||||||
|
* @author Gav Wood <i@gavwood.com>
|
||||||
|
* @date 2014
|
||||||
|
*
|
||||||
|
* The FixedHash fixed-size "hash" container type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "FixedHash.h"
|
||||||
|
#include "vector_ref.h"
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
// SHA-3 convenience routines.
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 hash of the given input and load it into the given output.
|
||||||
|
/// @returns false if o_output.size() != 32.
|
||||||
|
bool sha3(bytesConstRef _input, bytesRef o_output);
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
|
||||||
|
inline h256 sha3(bytesConstRef _input) { h256 ret; sha3(_input, ret.ref()); return ret; }
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
|
||||||
|
inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef(&_input)); }
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.
|
||||||
|
inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); }
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash.
|
||||||
|
template<unsigned N> inline h256 sha3(FixedHash<N> const& _input) { return sha3(_input.ref()); }
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data.
|
||||||
|
inline std::string sha3(std::string const& _input, bool _isNibbles) { return asString((_isNibbles ? sha3(fromHex(_input)) : sha3(bytesConstRef(&_input))).asBytes()); }
|
||||||
|
|
||||||
|
/// Calculate SHA3-256 MAC
|
||||||
|
inline void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) { sha3(_secret.toBytes() + _plain.toBytes()).ref().populate(_output); }
|
||||||
|
|
||||||
|
extern unsigned g_sha3Counter;
|
||||||
|
|
||||||
|
}
|
46
libdevcore/UndefMacros.h
Normal file
46
libdevcore/UndefMacros.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file UndefMacros.h
|
||||||
|
* @author Lefteris <lefteris@ethdev.com>
|
||||||
|
* @date 2015
|
||||||
|
*
|
||||||
|
* This header should be used to #undef some really evil macros defined by
|
||||||
|
* windows.h which result in conflict with our libsolidity/Token.h
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
|
||||||
|
#undef DELETE
|
||||||
|
#undef IN
|
||||||
|
#undef VOID
|
||||||
|
#undef THIS
|
||||||
|
#undef CONST
|
||||||
|
|
||||||
|
// Conflicting define on MinGW in windows.h
|
||||||
|
// windows.h(19): #define interface struct
|
||||||
|
#ifdef interface
|
||||||
|
#undef interface
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(DELETE) || defined(IN) || defined(VOID) || defined(THIS) || defined(CONST) || defined(interface)
|
||||||
|
|
||||||
|
#error "The preceding macros in this header file are reserved for V8's "\
|
||||||
|
"TOKEN_LIST. Please add a platform specific define above to undefine "\
|
||||||
|
"overlapping macros."
|
||||||
|
|
||||||
|
#endif
|
125
libdevcore/debugbreak.h
Normal file
125
libdevcore/debugbreak.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/* Copyright (c) 2013, Scott Tsai
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DEBUG_BREAK_H
|
||||||
|
#define DEBUG_BREAK_H
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
|
||||||
|
#define debug_break __debugbreak
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* gcc optimizers consider code after __builtin_trap() dead.
|
||||||
|
* Making __builtin_trap() unsuitable for breaking into the debugger */
|
||||||
|
DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
enum { HAVE_TRAP_INSTRUCTION = 1, };
|
||||||
|
__attribute__((gnu_inline, always_inline))
|
||||||
|
static void __inline__ trap_instruction(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile("int $0x03");
|
||||||
|
}
|
||||||
|
#elif defined(__thumb__)
|
||||||
|
enum { HAVE_TRAP_INSTRUCTION = 1, };
|
||||||
|
/* FIXME: handle __THUMB_INTERWORK__ */
|
||||||
|
__attribute__((gnu_inline, always_inline))
|
||||||
|
static void __inline__ trap_instruction(void)
|
||||||
|
{
|
||||||
|
/* See 'arm-linux-tdep.c' in GDB source.
|
||||||
|
* Both instruction sequences below works. */
|
||||||
|
#if 1
|
||||||
|
/* 'eabi_linux_thumb_le_breakpoint' */
|
||||||
|
__asm__ volatile(".inst 0xde01");
|
||||||
|
#else
|
||||||
|
/* 'eabi_linux_thumb2_le_breakpoint' */
|
||||||
|
__asm__ volatile(".inst.w 0xf7f0a000");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Known problem:
|
||||||
|
* After a breakpoint hit, can't stepi, step, or continue in GDB.
|
||||||
|
* 'step' stuck on the same instruction.
|
||||||
|
*
|
||||||
|
* Workaround: a new GDB command,
|
||||||
|
* 'debugbreak-step' is defined in debugbreak-gdb.py
|
||||||
|
* that does:
|
||||||
|
* (gdb) set $instruction_len = 2
|
||||||
|
* (gdb) tbreak *($pc + $instruction_len)
|
||||||
|
* (gdb) jump *($pc + $instruction_len)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#elif defined(__arm__) && !defined(__thumb__)
|
||||||
|
enum { HAVE_TRAP_INSTRUCTION = 1, };
|
||||||
|
__attribute__((gnu_inline, always_inline))
|
||||||
|
static void __inline__ trap_instruction(void)
|
||||||
|
{
|
||||||
|
/* See 'arm-linux-tdep.c' in GDB source,
|
||||||
|
* 'eabi_linux_arm_le_breakpoint' */
|
||||||
|
__asm__ volatile(".inst 0xe7f001f0");
|
||||||
|
/* Has same known problem and workaround
|
||||||
|
* as Thumb mode */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
enum { HAVE_TRAP_INSTRUCTION = 0, };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((gnu_inline, always_inline))
|
||||||
|
static void __inline__ debug_break(void)
|
||||||
|
{
|
||||||
|
if (HAVE_TRAP_INSTRUCTION) {
|
||||||
|
#if defined(ETH_EMSCRIPTEN)
|
||||||
|
asm("debugger");
|
||||||
|
#else
|
||||||
|
trap_instruction();
|
||||||
|
#endif
|
||||||
|
} else if (DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP) {
|
||||||
|
/* raises SIGILL on Linux x86{,-64}, to continue in gdb:
|
||||||
|
* (gdb) handle SIGILL stop nopass
|
||||||
|
* */
|
||||||
|
__builtin_trap();
|
||||||
|
} else {
|
||||||
|
raise(SIGTRAP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
360
libdevcore/picosha2.h
Normal file
360
libdevcore/picosha2.h
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (C) 2014 okdshin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef PICOSHA2_H
|
||||||
|
#define PICOSHA2_H
|
||||||
|
//picosha2:20140213
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <iterator>
|
||||||
|
#include <cassert>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace picosha2
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline uint8_t mask_8bit(uint8_t x){
|
||||||
|
return x&0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t mask_32bit(uint32_t x){
|
||||||
|
return x&0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint32_t add_constant[64] = {
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||||
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||||
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||||
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||||
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t initial_message_digest[8] = {
|
||||||
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||||
|
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||||
|
};
|
||||||
|
|
||||||
|
inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
|
||||||
|
return (x&y)^((~x)&z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
|
||||||
|
return (x&y)^(x&z)^(y&z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t rotr(uint32_t x, std::size_t n){
|
||||||
|
assert(n < 32);
|
||||||
|
return mask_32bit((x>>n)|(x<<(32-n)));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t bsig0(uint32_t x){
|
||||||
|
return rotr(x, 2)^rotr(x, 13)^rotr(x, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t bsig1(uint32_t x){
|
||||||
|
return rotr(x, 6)^rotr(x, 11)^rotr(x, 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t shr(uint32_t x, std::size_t n){
|
||||||
|
assert(n < 32);
|
||||||
|
return x >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t ssig0(uint32_t x){
|
||||||
|
return rotr(x, 7)^rotr(x, 18)^shr(x, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t ssig1(uint32_t x){
|
||||||
|
return rotr(x, 17)^rotr(x, 19)^shr(x, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaIter1, typename RaIter2>
|
||||||
|
void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){
|
||||||
|
(void)last; // FIXME: check this is valid
|
||||||
|
uint32_t w[64];
|
||||||
|
std::fill(w, w+64, 0);
|
||||||
|
for(std::size_t i = 0; i < 16; ++i){
|
||||||
|
w[i] = (static_cast<uint32_t>(mask_8bit(*(first+i*4)))<<24)
|
||||||
|
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+1)))<<16)
|
||||||
|
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+2)))<<8)
|
||||||
|
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+3))));
|
||||||
|
}
|
||||||
|
for(std::size_t i = 16; i < 64; ++i){
|
||||||
|
w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t a = *message_digest;
|
||||||
|
uint32_t b = *(message_digest+1);
|
||||||
|
uint32_t c = *(message_digest+2);
|
||||||
|
uint32_t d = *(message_digest+3);
|
||||||
|
uint32_t e = *(message_digest+4);
|
||||||
|
uint32_t f = *(message_digest+5);
|
||||||
|
uint32_t g = *(message_digest+6);
|
||||||
|
uint32_t h = *(message_digest+7);
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < 64; ++i){
|
||||||
|
uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i];
|
||||||
|
uint32_t temp2 = bsig0(a)+maj(a,b,c);
|
||||||
|
h = g;
|
||||||
|
g = f;
|
||||||
|
f = e;
|
||||||
|
e = mask_32bit(d+temp1);
|
||||||
|
d = c;
|
||||||
|
c = b;
|
||||||
|
b = a;
|
||||||
|
a = mask_32bit(temp1+temp2);
|
||||||
|
}
|
||||||
|
*message_digest += a;
|
||||||
|
*(message_digest+1) += b;
|
||||||
|
*(message_digest+2) += c;
|
||||||
|
*(message_digest+3) += d;
|
||||||
|
*(message_digest+4) += e;
|
||||||
|
*(message_digest+5) += f;
|
||||||
|
*(message_digest+6) += g;
|
||||||
|
*(message_digest+7) += h;
|
||||||
|
for(std::size_t i = 0; i < 8; ++i){
|
||||||
|
*(message_digest+i) = mask_32bit(*(message_digest+i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//namespace detail
|
||||||
|
|
||||||
|
template<typename InIter>
|
||||||
|
void output_hex(InIter first, InIter last, std::ostream& os){
|
||||||
|
os.setf(std::ios::hex, std::ios::basefield);
|
||||||
|
while(first != last){
|
||||||
|
os.width(2);
|
||||||
|
os.fill('0');
|
||||||
|
os << static_cast<unsigned int>(*first);
|
||||||
|
++first;
|
||||||
|
}
|
||||||
|
os.setf(std::ios::dec, std::ios::basefield);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InIter>
|
||||||
|
void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){
|
||||||
|
std::ostringstream oss;
|
||||||
|
output_hex(first, last, oss);
|
||||||
|
hex_str.assign(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InContainer>
|
||||||
|
void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){
|
||||||
|
bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InIter>
|
||||||
|
std::string bytes_to_hex_string(InIter first, InIter last){
|
||||||
|
std::string hex_str;
|
||||||
|
bytes_to_hex_string(first, last, hex_str);
|
||||||
|
return hex_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InContainer>
|
||||||
|
std::string bytes_to_hex_string(const InContainer& bytes){
|
||||||
|
std::string hex_str;
|
||||||
|
bytes_to_hex_string(bytes, hex_str);
|
||||||
|
return hex_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
class hash256_one_by_one {
|
||||||
|
public:
|
||||||
|
hash256_one_by_one(){
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(){
|
||||||
|
buffer_.clear();
|
||||||
|
std::fill(data_length_digits_, data_length_digits_+4, 0);
|
||||||
|
std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaIter>
|
||||||
|
void process(RaIter first, RaIter last){
|
||||||
|
add_to_data_length(std::distance(first, last));
|
||||||
|
std::copy(first, last, std::back_inserter(buffer_));
|
||||||
|
std::size_t i = 0;
|
||||||
|
for(;i+64 <= buffer_.size(); i+=64){
|
||||||
|
detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64);
|
||||||
|
}
|
||||||
|
buffer_.erase(buffer_.begin(), buffer_.begin()+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish(){
|
||||||
|
uint8_t temp[64];
|
||||||
|
std::fill(temp, temp+64, 0);
|
||||||
|
std::size_t remains = buffer_.size();
|
||||||
|
std::copy(buffer_.begin(), buffer_.end(), temp);
|
||||||
|
temp[remains] = 0x80;
|
||||||
|
|
||||||
|
if(remains > 55){
|
||||||
|
std::fill(temp+remains+1, temp+64, 0);
|
||||||
|
detail::hash256_block(h_, temp, temp+64);
|
||||||
|
std::fill(temp, temp+64-4, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::fill(temp+remains+1, temp+64-4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_data_bit_length(&(temp[56]));
|
||||||
|
detail::hash256_block(h_, temp, temp+64);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OutIter>
|
||||||
|
void get_hash_bytes(OutIter first, OutIter last)const{
|
||||||
|
for(const uint32_t* iter = h_; iter != h_+8; ++iter){
|
||||||
|
for(std::size_t i = 0; i < 4 && first != last; ++i){
|
||||||
|
*(first++) = detail::mask_8bit(static_cast<uint8_t>((*iter >> (24-8*i))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void add_to_data_length(uint32_t n) {
|
||||||
|
uint32_t carry = 0;
|
||||||
|
data_length_digits_[0] += n;
|
||||||
|
for(std::size_t i = 0; i < 4; ++i) {
|
||||||
|
data_length_digits_[i] += carry;
|
||||||
|
if(data_length_digits_[i] >= 65536u) {
|
||||||
|
data_length_digits_[i] -= 65536u;
|
||||||
|
carry = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void write_data_bit_length(uint8_t* begin) {
|
||||||
|
uint32_t data_bit_length_digits[4];
|
||||||
|
std::copy(
|
||||||
|
data_length_digits_, data_length_digits_+4,
|
||||||
|
data_bit_length_digits
|
||||||
|
);
|
||||||
|
|
||||||
|
// convert byte length to bit length (multiply 8 or shift 3 times left)
|
||||||
|
uint32_t carry = 0;
|
||||||
|
for(std::size_t i = 0; i < 4; ++i) {
|
||||||
|
uint32_t before_val = data_bit_length_digits[i];
|
||||||
|
data_bit_length_digits[i] <<= 3;
|
||||||
|
data_bit_length_digits[i] |= carry;
|
||||||
|
data_bit_length_digits[i] &= 65535u;
|
||||||
|
carry = (before_val >> (16-3)) & 65535u;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write data_bit_length
|
||||||
|
for(int i = 3; i >= 0; --i) {
|
||||||
|
(*begin++) = static_cast<uint8_t>(data_bit_length_digits[i] >> 8);
|
||||||
|
(*begin++) = static_cast<uint8_t>(data_bit_length_digits[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> buffer_;
|
||||||
|
uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)
|
||||||
|
uint32_t h_[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){
|
||||||
|
uint8_t hash[32];
|
||||||
|
hasher.get_hash_bytes(hash, hash+32);
|
||||||
|
return bytes_to_hex_string(hash, hash+32, hex_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){
|
||||||
|
std::string hex_str;
|
||||||
|
get_hash_hex_string(hasher, hex_str);
|
||||||
|
return hex_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaIter, typename OutIter>
|
||||||
|
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){
|
||||||
|
hash256_one_by_one hasher;
|
||||||
|
//hasher.init();
|
||||||
|
hasher.process(first, last);
|
||||||
|
hasher.finish();
|
||||||
|
hasher.get_hash_bytes(first2, last2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaIter, typename OutContainer>
|
||||||
|
void hash256(RaIter first, RaIter last, OutContainer& dst){
|
||||||
|
hash256(first, last, dst.begin(), dst.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaContainer, typename OutIter>
|
||||||
|
void hash256(const RaContainer& src, OutIter first, OutIter last){
|
||||||
|
hash256(src.begin(), src.end(), first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaContainer, typename OutContainer>
|
||||||
|
void hash256(const RaContainer& src, OutContainer& dst){
|
||||||
|
hash256(src.begin(), src.end(), dst.begin(), dst.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename RaIter>
|
||||||
|
void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){
|
||||||
|
uint8_t hashed[32];
|
||||||
|
hash256(first, last, hashed, hashed+32);
|
||||||
|
std::ostringstream oss;
|
||||||
|
output_hex(hashed, hashed+32, oss);
|
||||||
|
hex_str.assign(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaIter>
|
||||||
|
std::string hash256_hex_string(RaIter first, RaIter last){
|
||||||
|
std::string hex_str;
|
||||||
|
hash256_hex_string(first, last, hex_str);
|
||||||
|
return hex_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void hash256_hex_string(const std::string& src, std::string& hex_str){
|
||||||
|
hash256_hex_string(src.begin(), src.end(), hex_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaContainer>
|
||||||
|
void hash256_hex_string(const RaContainer& src, std::string& hex_str){
|
||||||
|
hash256_hex_string(src.begin(), src.end(), hex_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RaContainer>
|
||||||
|
std::string hash256_hex_string(const RaContainer& src){
|
||||||
|
return hash256_hex_string(src.begin(), src.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
}//namespace picosha2
|
||||||
|
|
||||||
|
#endif //PICOSHA2_H
|
120
libdevcore/vector_ref.h
Normal file
120
libdevcore/vector_ref.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef __INTEL_COMPILER
|
||||||
|
#pragma warning(disable:597) //will not be called for implicit or explicit conversions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A modifiable reference to an existing object or vector in memory.
|
||||||
|
*/
|
||||||
|
template <class _T>
|
||||||
|
class vector_ref
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = _T;
|
||||||
|
using element_type = _T;
|
||||||
|
using mutable_value_type = typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type;
|
||||||
|
|
||||||
|
static_assert(std::is_pod<value_type>::value, "vector_ref can only be used with PODs due to its low-level treatment of data.");
|
||||||
|
|
||||||
|
vector_ref(): m_data(nullptr), m_count(0) {}
|
||||||
|
/// Creates a new vector_ref to point to @a _count elements starting at @a _data.
|
||||||
|
vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {}
|
||||||
|
/// Creates a new vector_ref pointing to the data part of a string (given as pointer).
|
||||||
|
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const*, std::string*>::type _data): m_data(reinterpret_cast<_T*>(_data->data())), m_count(_data->size() / sizeof(_T)) {}
|
||||||
|
/// Creates a new vector_ref pointing to the data part of a vector (given as pointer).
|
||||||
|
vector_ref(typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {}
|
||||||
|
/// Creates a new vector_ref pointing to the data part of a string (given as reference).
|
||||||
|
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const&, std::string&>::type _data): m_data(reinterpret_cast<_T*>(_data.data())), m_count(_data.size() / sizeof(_T)) {}
|
||||||
|
#if DEV_LDB
|
||||||
|
vector_ref(ldb::Slice const& _s): m_data(reinterpret_cast<_T*>(_s.data())), m_count(_s.size() / sizeof(_T)) {}
|
||||||
|
#endif
|
||||||
|
explicit operator bool() const { return m_data && m_count; }
|
||||||
|
|
||||||
|
bool contentsEqual(std::vector<mutable_value_type> const& _c) const { if (!m_data || m_count == 0) return _c.empty(); else return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count * sizeof(_T)); }
|
||||||
|
std::vector<mutable_value_type> toVector() const { return std::vector<mutable_value_type>(m_data, m_data + m_count); }
|
||||||
|
std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>(reinterpret_cast<unsigned char const*>(m_data), reinterpret_cast<unsigned char const*>(m_data) + m_count * sizeof(_T)); }
|
||||||
|
std::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count * sizeof(_T)); }
|
||||||
|
|
||||||
|
template <class _T2> explicit operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>(reinterpret_cast<_T2*>(m_data), m_count * sizeof(_T) / sizeof(_T2)); }
|
||||||
|
operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); }
|
||||||
|
|
||||||
|
_T* data() const { return m_data; }
|
||||||
|
/// @returns the number of elements referenced (not necessarily number of bytes).
|
||||||
|
size_t count() const { return m_count; }
|
||||||
|
/// @returns the number of elements referenced (not necessarily number of bytes).
|
||||||
|
size_t size() const { return m_count; }
|
||||||
|
bool empty() const { return !m_count; }
|
||||||
|
/// @returns a new vector_ref pointing at the next chunk of @a size() elements.
|
||||||
|
vector_ref<_T> next() const { if (!m_data) return *this; else return vector_ref<_T>(m_data + m_count, m_count); }
|
||||||
|
/// @returns a new vector_ref which is a shifted and shortened view of the original data.
|
||||||
|
/// If this goes out of bounds in any way, returns an empty vector_ref.
|
||||||
|
/// If @a _count is ~size_t(0), extends the view to the end of the data.
|
||||||
|
vector_ref<_T> cropped(size_t _begin, size_t _count) const { if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); }
|
||||||
|
/// @returns a new vector_ref which is a shifted view of the original data (not going beyond it).
|
||||||
|
vector_ref<_T> cropped(size_t _begin) const { if (m_data && _begin <= m_count) return vector_ref<_T>(m_data + _begin, m_count - _begin); else return vector_ref<_T>(); }
|
||||||
|
void retarget(_T* _d, size_t _s) { m_data = _d; m_count = _s; }
|
||||||
|
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
|
||||||
|
template <class T> bool overlapsWith(vector_ref<T> _t) const { void const* f1 = data(); void const* t1 = data() + size(); void const* f2 = _t.data(); void const* t2 = _t.data() + _t.size(); return f1 < t2 && t1 > f2; }
|
||||||
|
/// Copies the contents of this vector_ref to the contents of @a _t, up to the max size of @a _t.
|
||||||
|
void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { if (overlapsWith(_t)) memmove(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); else memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }
|
||||||
|
/// Copies the contents of this vector_ref to the contents of @a _t, and zeros further trailing elements in @a _t.
|
||||||
|
void populate(vector_ref<typename std::remove_const<_T>::type> _t) const { copyTo(_t); memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count); }
|
||||||
|
/// Securely overwrite the memory.
|
||||||
|
/// @note adapted from OpenSSL's implementation.
|
||||||
|
void cleanse()
|
||||||
|
{
|
||||||
|
static unsigned char s_cleanseCounter = 0;
|
||||||
|
uint8_t* p = (uint8_t*)begin();
|
||||||
|
size_t const len = (uint8_t*)end() - p;
|
||||||
|
size_t loop = len;
|
||||||
|
size_t count = s_cleanseCounter;
|
||||||
|
while (loop--)
|
||||||
|
{
|
||||||
|
*(p++) = (uint8_t)count;
|
||||||
|
count += (17 + ((size_t)p & 0xf));
|
||||||
|
}
|
||||||
|
p = (uint8_t*)memchr((uint8_t*)begin(), (uint8_t)count, len);
|
||||||
|
if (p)
|
||||||
|
count += (63 + (size_t)p);
|
||||||
|
s_cleanseCounter = (uint8_t)count;
|
||||||
|
memset((uint8_t*)begin(), 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
_T* begin() { return m_data; }
|
||||||
|
_T* end() { return m_data + m_count; }
|
||||||
|
_T const* begin() const { return m_data; }
|
||||||
|
_T const* end() const { return m_data + m_count; }
|
||||||
|
|
||||||
|
_T& operator[](size_t _i) { assert(m_data); assert(_i < m_count); return m_data[_i]; }
|
||||||
|
_T const& operator[](size_t _i) const { assert(m_data); assert(_i < m_count); return m_data[_i]; }
|
||||||
|
|
||||||
|
bool operator==(vector_ref<_T> const& _cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; }
|
||||||
|
bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(_cmp); }
|
||||||
|
|
||||||
|
#if DEV_LDB
|
||||||
|
operator ldb::Slice() const { return ldb::Slice((char const*)m_data, m_count * sizeof(_T)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset() { m_data = nullptr; m_count = 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
_T* m_data;
|
||||||
|
size_t m_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class _T> vector_ref<_T const> ref(_T const& _t) { return vector_ref<_T const>(&_t, 1); }
|
||||||
|
template<class _T> vector_ref<_T> ref(_T& _t) { return vector_ref<_T>(&_t, 1); }
|
||||||
|
template<class _T> vector_ref<_T const> ref(std::vector<_T> const& _t) { return vector_ref<_T const>(&_t); }
|
||||||
|
template<class _T> vector_ref<_T> ref(std::vector<_T>& _t) { return vector_ref<_T>(&_t); }
|
||||||
|
|
||||||
|
}
|
@ -322,7 +322,8 @@ Assembly& Assembly::optimise(bool _enable, bool _isCreation, size_t _runs)
|
|||||||
count++;
|
count++;
|
||||||
|
|
||||||
{
|
{
|
||||||
ControlFlowGraph cfg(m_items);
|
// Control flow graph that resets knowledge at path joins.
|
||||||
|
ControlFlowGraph cfg(m_items, false);
|
||||||
AssemblyItems optimisedItems;
|
AssemblyItems optimisedItems;
|
||||||
for (BasicBlock const& block: cfg.optimisedBlocks())
|
for (BasicBlock const& block: cfg.optimisedBlocks())
|
||||||
{
|
{
|
||||||
|
@ -250,6 +250,10 @@ void ControlFlowGraph::gatherKnowledge()
|
|||||||
KnownStatePointer state = item.state;
|
KnownStatePointer state = item.state;
|
||||||
if (block.startState)
|
if (block.startState)
|
||||||
{
|
{
|
||||||
|
// We call reduceToCommonKnowledge even in the non-join setting to get the correct
|
||||||
|
// sequence number
|
||||||
|
if (!m_joinKnowledge)
|
||||||
|
state->reset();
|
||||||
state->reduceToCommonKnowledge(*block.startState, !item.blocksSeen.count(item.blockId));
|
state->reduceToCommonKnowledge(*block.startState, !item.blocksSeen.count(item.blockId));
|
||||||
if (*state == *block.startState)
|
if (*state == *block.startState)
|
||||||
continue;
|
continue;
|
||||||
|
@ -94,7 +94,11 @@ class ControlFlowGraph
|
|||||||
public:
|
public:
|
||||||
/// Initializes the control flow graph.
|
/// Initializes the control flow graph.
|
||||||
/// @a _items has to persist across the usage of this class.
|
/// @a _items has to persist across the usage of this class.
|
||||||
ControlFlowGraph(AssemblyItems const& _items): m_items(_items) {}
|
/// @a _joinKnowledge if true, reduces state knowledge to common base at the join of two paths
|
||||||
|
explicit ControlFlowGraph(AssemblyItems const& _items, bool _joinKnowledge = true):
|
||||||
|
m_items(_items),
|
||||||
|
m_joinKnowledge(_joinKnowledge)
|
||||||
|
{}
|
||||||
/// @returns vector of basic blocks in the order they should be used in the final code.
|
/// @returns vector of basic blocks in the order they should be used in the final code.
|
||||||
/// Should be called only once.
|
/// Should be called only once.
|
||||||
BasicBlocks optimisedBlocks();
|
BasicBlocks optimisedBlocks();
|
||||||
@ -112,6 +116,7 @@ private:
|
|||||||
|
|
||||||
unsigned m_lastUsedId = 0;
|
unsigned m_lastUsedId = 0;
|
||||||
AssemblyItems const& m_items;
|
AssemblyItems const& m_items;
|
||||||
|
bool m_joinKnowledge = true;
|
||||||
std::map<BlockId, BasicBlock> m_blocks;
|
std::map<BlockId, BasicBlock> m_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
62
libevmasm/EVMSchedule.h
Normal file
62
libevmasm/EVMSchedule.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file EVMSchedule.h
|
||||||
|
* @author Gav <i@gavwood.com>
|
||||||
|
* @author Christian <c@ethdev.com>
|
||||||
|
* @date 2015
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
namespace solidity
|
||||||
|
{
|
||||||
|
|
||||||
|
struct EVMSchedule
|
||||||
|
{
|
||||||
|
unsigned stackLimit = 1024;
|
||||||
|
unsigned expGas = 10;
|
||||||
|
unsigned expByteGas = 10;
|
||||||
|
unsigned sha3Gas = 30;
|
||||||
|
unsigned sha3WordGas = 6;
|
||||||
|
unsigned sloadGas = 50;
|
||||||
|
unsigned sstoreSetGas = 20000;
|
||||||
|
unsigned sstoreResetGas = 5000;
|
||||||
|
unsigned sstoreRefundGas = 15000;
|
||||||
|
unsigned jumpdestGas = 1;
|
||||||
|
unsigned logGas = 375;
|
||||||
|
unsigned logDataGas = 8;
|
||||||
|
unsigned logTopicGas = 375;
|
||||||
|
unsigned createGas = 32000;
|
||||||
|
unsigned callGas = 40;
|
||||||
|
unsigned callStipend = 2300;
|
||||||
|
unsigned callValueTransferGas = 9000;
|
||||||
|
unsigned callNewAccountGas = 25000;
|
||||||
|
unsigned suicideRefundGas = 24000;
|
||||||
|
unsigned memoryGas = 3;
|
||||||
|
unsigned quadCoeffDiv = 512;
|
||||||
|
unsigned createDataGas = 200;
|
||||||
|
unsigned txGas = 21000;
|
||||||
|
unsigned txCreateGas = 53000;
|
||||||
|
unsigned txDataZeroGas = 4;
|
||||||
|
unsigned txDataNonZeroGas = 68;
|
||||||
|
unsigned copyGas = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -104,6 +104,7 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// Zero-initialises (the data part of) an already allocated memory array.
|
/// Zero-initialises (the data part of) an already allocated memory array.
|
||||||
|
/// Length has to be nonzero!
|
||||||
/// Stack pre: <length> <memptr>
|
/// Stack pre: <length> <memptr>
|
||||||
/// Stack post: <updated_memptr>
|
/// Stack post: <updated_memptr>
|
||||||
void zeroInitialiseMemoryArray(ArrayType const& _type);
|
void zeroInitialiseMemoryArray(ArrayType const& _type);
|
||||||
|
@ -792,15 +792,18 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
utils().storeFreeMemoryPointer();
|
utils().storeFreeMemoryPointer();
|
||||||
// Stack: memptr requested_length
|
// Stack: memptr requested_length
|
||||||
|
|
||||||
|
// Check if length is zero
|
||||||
|
m_context << Instruction::DUP1 << Instruction::ISZERO;
|
||||||
|
auto skipInit = m_context.appendConditionalJump();
|
||||||
|
|
||||||
// We only have to initialise if the base type is a not a value type.
|
// We only have to initialise if the base type is a not a value type.
|
||||||
if (dynamic_cast<ReferenceType const*>(arrayType.baseType().get()))
|
if (dynamic_cast<ReferenceType const*>(arrayType.baseType().get()))
|
||||||
{
|
{
|
||||||
m_context << Instruction::DUP2 << u256(32) << Instruction::ADD;
|
m_context << Instruction::DUP2 << u256(32) << Instruction::ADD;
|
||||||
utils().zeroInitialiseMemoryArray(arrayType);
|
utils().zeroInitialiseMemoryArray(arrayType);
|
||||||
m_context << Instruction::POP;
|
|
||||||
}
|
}
|
||||||
else
|
m_context << skipInit;
|
||||||
m_context << Instruction::POP;
|
m_context << Instruction::POP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
34
scripts/build_emscripten.sh
Executable file
34
scripts/build_emscripten.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script for building Solidity for emscripten.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# https://solidity.readthedocs.org
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" != "darwin"* ]]; then
|
||||||
|
./scripts/travis-emscripten/install_deps.sh
|
||||||
|
docker run -v $(pwd):/src trzeci/emscripten:sdk-tag-1.35.4-64bit ./scripts/travis-emscripten/build_emscripten.sh
|
||||||
|
fi
|
33
scripts/docs.sh
Normal file
33
scripts/docs.sh
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script to build the Solidity Sphinx documentation locally.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# https://solidity.readthedocs.org
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
# We aren't building docs locally for macOS at the moment
|
||||||
|
else
|
||||||
|
cd docs && sphinx-build -nW -b html -d _build/doctrees . _build/html && cd ..
|
||||||
|
fi
|
65
scripts/fix_homebrew_paths_in_standalone_zip.py
Executable file
65
scripts/fix_homebrew_paths_in_standalone_zip.py
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This Python script is used within the OS X release process, to ensure
|
||||||
|
# that the standalone OS X ZIP files which we make are actually
|
||||||
|
# standalone, and not implicitly dependent on Homebrew installs for
|
||||||
|
# external libraries which we use.
|
||||||
|
#
|
||||||
|
# This implicit dependencies seem to show up only where we have
|
||||||
|
# external dependencies which are dependent on each other, and the
|
||||||
|
# path from one to another is an absolute path to "/usr/local/opt",
|
||||||
|
# the Homebrew install location. External dependencies which only
|
||||||
|
# depend on system libraries are fine. Our main applications seem
|
||||||
|
# to be fine.
|
||||||
|
#
|
||||||
|
# An example of a dependency which requires this fix-up at the time
|
||||||
|
# of writing is the following dependency edge:
|
||||||
|
#
|
||||||
|
# libjsonrpccpp-client.0.dylib
|
||||||
|
# -> /usr/local/opt/jsoncpp/lib/libjsoncpp.0.dylib
|
||||||
|
#
|
||||||
|
# See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac
|
||||||
|
# for a little overview of "install_name_tool" and "otool".
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def readDependencies(fname):
|
||||||
|
with open(fname) as f:
|
||||||
|
o = subprocess.Popen(['otool', '-L', fname], stdout=subprocess.PIPE)
|
||||||
|
for line in o.stdout:
|
||||||
|
if line[0] == '\t':
|
||||||
|
library = line.split(' ', 1)[0][1:]
|
||||||
|
if library.startswith("/usr/local/lib") or library.startswith("/usr/local/opt") or library.startswith("/Users/"):
|
||||||
|
if (os.path.basename(library) != os.path.basename(fname)):
|
||||||
|
command = "install_name_tool -change " + \
|
||||||
|
library + " @executable_path/./" + \
|
||||||
|
os.path.basename(library) + " " + fname
|
||||||
|
print command
|
||||||
|
os.system("chmod +w " + fname)
|
||||||
|
os.system(command)
|
||||||
|
|
||||||
|
root = sys.argv[1]
|
||||||
|
for (dirpath, dirnames, filenames) in os.walk(root):
|
||||||
|
for filename in filenames:
|
||||||
|
readDependencies(os.path.join(root, filename))
|
61
scripts/install_deps.bat
Normal file
61
scripts/install_deps.bat
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
REM ---------------------------------------------------------------------------
|
||||||
|
REM Batch file for installing pre-requisite packages for solidity on
|
||||||
|
REM Windows platforms. That is implemented using CMake targets which
|
||||||
|
REM extract pre-built ZIPs hosted on GitHub into "deps\install_deps".
|
||||||
|
REM
|
||||||
|
REM See https://github.com/ethereum/cpp-dependencies
|
||||||
|
REM
|
||||||
|
REM The CMake files then point into that directory as an alternative
|
||||||
|
REM to the Homebrew, PPA or other global package server locations
|
||||||
|
REM available on Linux and UNIX platforms.
|
||||||
|
REM
|
||||||
|
REM The lack of a standard C++ packaging system for Windows is problematic
|
||||||
|
REM for us, and we have considered various options for improving the
|
||||||
|
REM situation, such as the following:
|
||||||
|
REM
|
||||||
|
REM See "Windows - Add support for Chocolatey packages"
|
||||||
|
REM https://github.com/ethereum/webthree-umbrella/issues/345
|
||||||
|
REM
|
||||||
|
REM See "Windows - Try to use NuGet C++ packages"
|
||||||
|
REM https://github.com/ethereum/webthree-umbrella/issues/509
|
||||||
|
REM
|
||||||
|
REM See "CM - Can we switch to NuGet delivery for our external dependencies"
|
||||||
|
REM https://github.com/ethereum/webthree-umbrella/issues/376
|
||||||
|
REM
|
||||||
|
REM Another possible option, which would benefit build robustness on
|
||||||
|
REM multiple platforms, not just Windows, is to add dependencies as
|
||||||
|
REM git-submodules (or downloading on demand) so that we aren'targets
|
||||||
|
REM depend on platform-specific packaging systems at all. We have
|
||||||
|
REM already done just that for LLVM within evmjit. The downside of
|
||||||
|
REM that approach is that those dependencies then need to be
|
||||||
|
REM built-from-source, which adds time to the build process. It
|
||||||
|
REM gives us an unbeatable degree of control, though, because we
|
||||||
|
REM then perfectly control versioning and build flags for the binaries
|
||||||
|
REM for those packages.
|
||||||
|
REM
|
||||||
|
REM The documentation for solidity is hosted at:
|
||||||
|
REM
|
||||||
|
REM http://solidity.readthedocs.org
|
||||||
|
REM
|
||||||
|
REM ---------------------------------------------------------------------------
|
||||||
|
REM This file is part of solidity.
|
||||||
|
REM
|
||||||
|
REM solidity is free software: you can redistribute it and/or modify
|
||||||
|
REM it under the terms of the GNU General Public License as published by
|
||||||
|
REM the Free Software Foundation, either version 3 of the License, or
|
||||||
|
REM (at your option) any later version.
|
||||||
|
REM
|
||||||
|
REM solidity is distributed in the hope that it will be useful,
|
||||||
|
REM but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
REM GNU General Public License for more details.
|
||||||
|
REM
|
||||||
|
REM You should have received a copy of the GNU General Public License
|
||||||
|
REM along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
REM
|
||||||
|
REM Copyright (c) 2016 solidity contributors.
|
||||||
|
REM ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
cmake -P deps\install_deps.cmake
|
363
scripts/install_deps.sh
Executable file
363
scripts/install_deps.sh
Executable file
@ -0,0 +1,363 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script for installing pre-requisite packages for solidity on a
|
||||||
|
# variety of Linux and other UNIX-derived platforms.
|
||||||
|
#
|
||||||
|
# This is an "infrastucture-as-code" alternative to the manual build
|
||||||
|
# instructions pages which we previously maintained at:
|
||||||
|
# http://solidity.readthedocs.io/en/latest/installing-solidity.html
|
||||||
|
#
|
||||||
|
# The aim of this script is to simplify things down to the following basic
|
||||||
|
# flow for all supported operating systems:
|
||||||
|
#
|
||||||
|
# - git clone --recursive
|
||||||
|
# - ./install_deps.sh
|
||||||
|
# - cmake && make
|
||||||
|
#
|
||||||
|
# At the time of writing we are assuming that 'lsb_release' is present for all
|
||||||
|
# Linux distros, which is not a valid assumption. We will need a variety of
|
||||||
|
# approaches to actually get this working across all the distros which people
|
||||||
|
# are using.
|
||||||
|
#
|
||||||
|
# See http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name
|
||||||
|
# for some more background on this common problem.
|
||||||
|
#
|
||||||
|
# TODO - There is no support here yet for cross-builds in any form, only
|
||||||
|
# native builds. Expanding the functionality here to cover the mobile,
|
||||||
|
# wearable and SBC platforms covered by doublethink and EthEmbedded would
|
||||||
|
# also bring in support for Android, iOS, watchOS, tvOS, Tizen, Sailfish,
|
||||||
|
# Maemo, MeeGo and Yocto.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# http://solidity.readthedocs.io/
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Check for 'uname' and abort if it is not available.
|
||||||
|
uname -v > /dev/null 2>&1 || { echo >&2 "ERROR - solidity requires 'uname' to identify the platform."; exit 1; }
|
||||||
|
|
||||||
|
case $(uname -s) in
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# macOS
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Darwin)
|
||||||
|
case $(sw_vers -productVersion | awk -F . '{print $1"."$2}') in
|
||||||
|
10.9)
|
||||||
|
echo "Installing solidity dependencies on OS X 10.9 Mavericks."
|
||||||
|
;;
|
||||||
|
10.10)
|
||||||
|
echo "Installing solidity dependencies on OS X 10.10 Yosemite."
|
||||||
|
;;
|
||||||
|
10.11)
|
||||||
|
echo "Installing solidity dependencies on OS X 10.11 El Capitan."
|
||||||
|
;;
|
||||||
|
10.12)
|
||||||
|
echo "Installing solidity dependencies on macOS 10.12 Sierra."
|
||||||
|
echo ""
|
||||||
|
echo "NOTE - You are in unknown territory with this preview OS."
|
||||||
|
echo "Even Homebrew doesn't have official support yet, and there are"
|
||||||
|
echo "known issues (see https://github.com/ethereum/webthree-umbrella/issues/614)."
|
||||||
|
echo "If you would like to partner with us to work through these issues, that"
|
||||||
|
echo "would be fantastic. Please just comment on that issue. Thanks!"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported macOS version."
|
||||||
|
echo "We only support Mavericks, Yosemite and El Capitan, with work-in-progress on Sierra."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check for Homebrew install and abort if it is not installed.
|
||||||
|
brew -v > /dev/null 2>&1 || { echo >&2 "ERROR - solidity requires a Homebrew install. See http://brew.sh."; exit 1; }
|
||||||
|
|
||||||
|
brew update
|
||||||
|
brew upgrade
|
||||||
|
|
||||||
|
brew install boost
|
||||||
|
brew install cmake
|
||||||
|
brew install jsoncpp
|
||||||
|
|
||||||
|
# We should really 'brew install' our eth client here, but at the time of writing
|
||||||
|
# the bottle is known broken, so we will just cheat and use a hardcoded ZIP for
|
||||||
|
# the time being, which is good enough. The cause of the breaks will go away
|
||||||
|
# when we commit the repository reorg changes anyway.
|
||||||
|
curl -L -O https://github.com/bobsummerwill/cpp-ethereum/releases/download/v1.3.0/cpp-ethereum-osx-mavericks-v1.3.0.zip
|
||||||
|
unzip cpp-ethereum-osx-mavericks-v1.3.0.zip
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# FreeBSD
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FreeBSD)
|
||||||
|
echo "Installing solidity dependencies on FreeBSD."
|
||||||
|
echo "ERROR - 'install_deps.sh' doesn't have FreeBSD support yet."
|
||||||
|
echo "Please let us know if you see this error message, and we can work out what is missing."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Linux
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Linux)
|
||||||
|
case $(lsb_release -is) in
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Arch Linux
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Arch)
|
||||||
|
#Arch
|
||||||
|
echo "Installing solidity dependencies on Arch Linux."
|
||||||
|
|
||||||
|
# All our dependencies can be found in the Arch Linux official repositories.
|
||||||
|
# See https://wiki.archlinux.org/index.php/Official_repositories
|
||||||
|
sudo pacman -Sy \
|
||||||
|
base-devel \
|
||||||
|
boost \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Alpine Linux
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Alpine)
|
||||||
|
#Alpine
|
||||||
|
echo "Installing solidity dependencies on Alpine Linux."
|
||||||
|
echo "ERROR - 'install_deps.sh' doesn't have Alpine Linux support yet."
|
||||||
|
echo "See http://solidity.readthedocs.io/en/latest/installing-solidity.html for manual instructions."
|
||||||
|
echo "If you would like to get 'install_deps.sh' working for Alpine Linux, that would be fantastic."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
echo "See also https://github.com/ethereum/webthree-umbrella/issues/495 where we are working through Alpine support."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Debian
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Debian)
|
||||||
|
#Debian
|
||||||
|
case $(lsb_release -cs) in
|
||||||
|
wheezy)
|
||||||
|
#wheezy
|
||||||
|
echo "Installing solidity dependencies on Debian Wheezy (7.x)."
|
||||||
|
echo "ERROR - 'install_deps.sh' doesn't have Debian Wheezy support yet."
|
||||||
|
echo "See http://solidity.readthedocs.io/en/latest/installing-solidity.html for manual instructions."
|
||||||
|
echo "If you would like to get 'install_deps.sh' working for Debian Wheezy, that would be fantastic."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
echo "See also https://github.com/ethereum/webthree-umbrella/issues/495 where we are working through Alpine support."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
jessie)
|
||||||
|
#jessie
|
||||||
|
echo "Installing solidity dependencies on Debian Jesse (8.x)."
|
||||||
|
;;
|
||||||
|
stretch)
|
||||||
|
#stretch
|
||||||
|
echo "Installing solidity dependencies on Debian Stretch (9.x)."
|
||||||
|
echo "ERROR - 'install_deps.sh' doesn't have Debian Stretch support yet."
|
||||||
|
echo "See http://solidity.readthedocs.io/en/latest/installing-solidity.html for manual instructions."
|
||||||
|
echo "If you would like to get 'install_deps.sh' working for Debian Stretch, that would be fantastic."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
#other Debian
|
||||||
|
echo "Installing solidity dependencies on unknown Debian version."
|
||||||
|
echo "ERROR - Debian Jessie is the only Debian version which solidity has been tested on."
|
||||||
|
echo "If you are using a different release and would like to get 'install_deps.sh'"
|
||||||
|
echo "working for that release that would be fantastic."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Install "normal packages"
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
g++ \
|
||||||
|
gcc \
|
||||||
|
git \
|
||||||
|
libboost-all-dev \
|
||||||
|
libjsoncpp-dev \
|
||||||
|
unzip
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Fedora
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Fedora)
|
||||||
|
#Fedora
|
||||||
|
echo "Installing solidity dependencies on Fedora."
|
||||||
|
|
||||||
|
# Install "normal packages"
|
||||||
|
# See https://fedoraproject.org/wiki/Package_management_system.
|
||||||
|
dnf install \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
|
boost-devel \
|
||||||
|
cmake \
|
||||||
|
gcc \
|
||||||
|
gcc-c++ \
|
||||||
|
git \
|
||||||
|
libtool
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# OpenSUSE
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
"openSUSE project")
|
||||||
|
#openSUSE
|
||||||
|
echo "Installing solidity dependencies on openSUSE."
|
||||||
|
echo "ERROR - 'install_deps.sh' doesn't have openSUSE support yet."
|
||||||
|
echo "See http://solidity.readthedocs.io/en/latest/installing-solidity.html for manual instructions."
|
||||||
|
echo "If you would like to get 'install_deps.sh' working for openSUSE, that would be fantastic."
|
||||||
|
echo "See https://github.com/ethereum/webthree-umbrella/issues/552."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Ubuntu
|
||||||
|
#
|
||||||
|
# TODO - I wonder whether all of the Ubuntu-variants need some special
|
||||||
|
# treatment?
|
||||||
|
#
|
||||||
|
# TODO - We should also test this code on Ubuntu Server, Ubuntu Snappy Core
|
||||||
|
# and Ubuntu Phone.
|
||||||
|
#
|
||||||
|
# TODO - Our Ubuntu build is only working for amd64 and i386 processors.
|
||||||
|
# It would be good to add armel, armhf and arm64.
|
||||||
|
# See https://github.com/ethereum/webthree-umbrella/issues/228.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Ubuntu)
|
||||||
|
#Ubuntu
|
||||||
|
case $(lsb_release -cs) in
|
||||||
|
trusty)
|
||||||
|
#trusty
|
||||||
|
echo "Installing solidity dependencies on Ubuntu Trusty Tahr (14.04)."
|
||||||
|
;;
|
||||||
|
utopic)
|
||||||
|
#utopic
|
||||||
|
echo "Installing solidity dependencies on Ubuntu Utopic Unicorn (14.10)."
|
||||||
|
;;
|
||||||
|
vivid)
|
||||||
|
#vivid
|
||||||
|
echo "Installing solidity dependencies on Ubuntu Vivid Vervet (15.04)."
|
||||||
|
;;
|
||||||
|
wily)
|
||||||
|
#wily
|
||||||
|
echo "Installing solidity dependencies on Ubuntu Wily Werewolf (15.10)."
|
||||||
|
;;
|
||||||
|
xenial)
|
||||||
|
#xenial
|
||||||
|
echo "Installing solidity dependencies on Ubuntu Xenial Xerus (16.04)."
|
||||||
|
;;
|
||||||
|
yakkety)
|
||||||
|
#yakkety
|
||||||
|
echo "Installing solidity dependencies on Ubuntu Yakkety Yak (16.10)."
|
||||||
|
echo ""
|
||||||
|
echo "NOTE - You are in unknown territory with this preview OS."
|
||||||
|
echo "We will need to update the Ethereum PPAs, work through build and runtime breaks, etc."
|
||||||
|
echo "See https://github.com/ethereum/webthree-umbrella/issues/624."
|
||||||
|
echo "If you would like to partner with us to work through these, that"
|
||||||
|
echo "would be fantastic. Please just comment on that issue. Thanks!"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
#other Ubuntu
|
||||||
|
echo "ERROR - Unknown or unsupported Ubuntu version."
|
||||||
|
echo "We only support Trusty, Utopic, Vivid, Wily and Xenial, with work-in-progress on Yakkety."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
libboost-all-dev \
|
||||||
|
libjsoncpp-dev
|
||||||
|
|
||||||
|
# Install 'eth', for use in the Solidity Tests-over-IPC.
|
||||||
|
sudo add-apt-repository -y ppa:ethereum/ethereum
|
||||||
|
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install eth
|
||||||
|
|
||||||
|
# And install the English language package and reconfigure the locales.
|
||||||
|
# We really shouldn't need to do this, and should instead force our locales to "C"
|
||||||
|
# within our application runtimes, because this issue shows up on multiple Linux distros,
|
||||||
|
# and each will need fixing in the install steps, where we should really just fix it once
|
||||||
|
# in the code.
|
||||||
|
#
|
||||||
|
# See https://github.com/ethereum/webthree-umbrella/issues/169
|
||||||
|
sudo apt-get -y install language-pack-en-base
|
||||||
|
sudo dpkg-reconfigure locales
|
||||||
|
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Other (unknown) Linux
|
||||||
|
# Major and medium distros which we are missing would include Mint, CentOS,
|
||||||
|
# RHEL, Raspbian, Cygwin, OpenWrt, gNewSense, Trisquel and SteamOS.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#other Linux
|
||||||
|
echo "ERROR - Unsupported or unidentified Linux distro."
|
||||||
|
echo "See http://solidity.readthedocs.io/en/latest/installing-solidity.html for manual instructions."
|
||||||
|
echo "If you would like to get your distro working, that would be fantastic."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Other platform (not Linux, FreeBSD or macOS).
|
||||||
|
# Not sure what might end up here?
|
||||||
|
# Maybe OpenBSD, NetBSD, AIX, Solaris, HP-UX?
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*)
|
||||||
|
#other
|
||||||
|
echo "ERROR - Unsupported or unidentified operating system."
|
||||||
|
echo "See http://solidity.readthedocs.io/en/latest/installing-solidity.html for manual instructions."
|
||||||
|
echo "If you would like to get your operating system working, that would be fantastic."
|
||||||
|
echo "Drop us a message at https://gitter.im/ethereum/solidity."
|
||||||
|
;;
|
||||||
|
esac
|
34
scripts/release.bat
Normal file
34
scripts/release.bat
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
REM ---------------------------------------------------------------------------
|
||||||
|
REM Batch file for implementing release flow for solidity for Windows.
|
||||||
|
REM
|
||||||
|
REM The documentation for solidity is hosted at:
|
||||||
|
REM
|
||||||
|
REM https://solidity.readthedocs.org
|
||||||
|
REM
|
||||||
|
REM ---------------------------------------------------------------------------
|
||||||
|
REM This file is part of solidity.
|
||||||
|
REM
|
||||||
|
REM solidity is free software: you can redistribute it and/or modify
|
||||||
|
REM it under the terms of the GNU General Public License as published by
|
||||||
|
REM the Free Software Foundation, either version 3 of the License, or
|
||||||
|
REM (at your option) any later version.
|
||||||
|
REM
|
||||||
|
REM solidity is distributed in the hope that it will be useful,
|
||||||
|
REM but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
REM GNU General Public License for more details.
|
||||||
|
REM
|
||||||
|
REM You should have received a copy of the GNU General Public License
|
||||||
|
REM along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
REM
|
||||||
|
REM Copyright (c) 2016 solidity contributors.
|
||||||
|
REM ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set CONFIGURATION=%1
|
||||||
|
|
||||||
|
REM TODO - Add soltest\%CONFIGURATION%\soltest.exe, when that is buildable.
|
||||||
|
7z a solidity-develop-windows.zip ^
|
||||||
|
.\build\solc\%CONFIGURATION%\solc.exe ^
|
||||||
|
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x86\Microsoft.VC140.CRT\msvc*.dll"
|
92
scripts/release.sh
Executable file
92
scripts/release.sh
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script implementing release flow for solidity for Linux and macOS.
|
||||||
|
#
|
||||||
|
# TODO - At the time of writing, we only have ZIPs working. Need to hook up
|
||||||
|
# support for Homebrew and PPAs.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# https://solidity.readthedocs.org
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ZIP_SUFFIX=$1
|
||||||
|
ZIP_TEMP_DIR=$(pwd)/build/zip/
|
||||||
|
|
||||||
|
# There is an implicit assumption here that we HAVE to run from root directory.
|
||||||
|
REPO_ROOT=$(pwd)
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
DLL_EXT=dylib
|
||||||
|
else
|
||||||
|
DLL_EXT=so
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $ZIP_TEMP_DIR
|
||||||
|
|
||||||
|
# Copy all the solidity executables into a temporary directory prior to ZIP creation
|
||||||
|
|
||||||
|
cp $REPO_ROOT/build/lllc/lllc $ZIP_TEMP_DIR
|
||||||
|
cp $REPO_ROOT/build/solc/solc $ZIP_TEMP_DIR
|
||||||
|
cp $REPO_ROOT/build/soltest/soltest $ZIP_TEMP_DIR
|
||||||
|
|
||||||
|
# Copy all the dynamic libraries into a temporary directory prior to ZIP creation.
|
||||||
|
# There are a lot of these, and it would be great if we didn't have to worry about them.
|
||||||
|
# There is work-in-progress to support static-linkage on the UNIX platforms, which
|
||||||
|
# is most promising on Alpine Linux using musl. macOS doesn't support statically
|
||||||
|
# linked binaries (ie. executables which make direct system calls to the kernel.
|
||||||
|
#
|
||||||
|
# See https://developer.apple.com/library/mac/qa/qa1118/_index.html.
|
||||||
|
# See https://github.com/ethereum/webthree-umbrella/issues/495.
|
||||||
|
|
||||||
|
cp $REPO_ROOT/build/libdevcore/*.$DLL_EXT $ZIP_TEMP_DIR
|
||||||
|
cp $REPO_ROOT/build/libevmasm/*.$DLL_EXT $ZIP_TEMP_DIR
|
||||||
|
cp $REPO_ROOT/build/libsolidity/*.$DLL_EXT $ZIP_TEMP_DIR
|
||||||
|
|
||||||
|
# For macOS, we also copy the dynamic libraries for our external dependencies.
|
||||||
|
# When building from source on your own machine, these libraries will be installed
|
||||||
|
# globally, using Homebrew, but we don't want to rely on that for these ZIPs, so
|
||||||
|
# we copy these into the ZIP temporary directory too.
|
||||||
|
#
|
||||||
|
# TODO - So what happens for Linux and other UNIX distros in this case?
|
||||||
|
# There will be runtime dependencies on equivalent SO files being present, likely in
|
||||||
|
# a completely analogous way. Does that mean that ZIPs are actually useless on such
|
||||||
|
# distros, because there will be symbol links to global install locations (distro-specific)
|
||||||
|
# and those files will just be missing on the target machines?
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
cp /usr/local/opt/jsoncpp/lib/libjsoncpp.1.dylib $ZIP_TEMP_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For macOS, we run a fix-up script which alters all of the symbolic links within
|
||||||
|
# the executables and dynamic libraries such that the ZIP becomes self-contained, by
|
||||||
|
# revectoring all the dylib references to be relative to the directory containing the
|
||||||
|
# application, so that the ZIPs are self-contained, with the only external references
|
||||||
|
# being for kernel-level dylibs.
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
python $REPO_ROOT/scripts/fix_homebrew_paths_in_standalone_zip.py $ZIP_TEMP_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# And ZIP it all up, with a filename suffix passed in on the command-line.
|
||||||
|
|
||||||
|
zip -j $REPO_ROOT/solidity-develop-$ZIP_SUFFIX.zip $ZIP_TEMP_DIR/*
|
69
scripts/tests.sh
Executable file
69
scripts/tests.sh
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script to execute the Solidity tests.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# https://solidity.readthedocs.org
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# There is an implicit assumption here that we HAVE to run from root directory.
|
||||||
|
REPO_ROOT=$(pwd)
|
||||||
|
|
||||||
|
# This conditional is only needed because we don't have a working Homebrew
|
||||||
|
# install for `eth` at the time of writing, so we unzip the ZIP file locally
|
||||||
|
# instead. This will go away soon.
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
ETH_PATH="$REPO_ROOT/eth"
|
||||||
|
else
|
||||||
|
ETH_PATH="eth"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This trailing ampersand directs the shell to run the command in the background,
|
||||||
|
# that is, it is forked and run in a separate sub-shell, as a job,
|
||||||
|
# asynchronously. The shell will immediately return the return status of 0 for
|
||||||
|
# true and continue as normal, either processing further commands in a script
|
||||||
|
# or returning the cursor focus back to the user in a Linux terminal.
|
||||||
|
$ETH_PATH --test -d /tmp/test &
|
||||||
|
|
||||||
|
# Wait until the IPC endpoint is available. That won't be available instantly.
|
||||||
|
# The node needs to get a little way into its startup sequence before the IPC
|
||||||
|
# is available and is ready for the unit-tests to start talking to it.
|
||||||
|
while [ ! -S /tmp/test/geth.ipc ]; do sleep 2; done
|
||||||
|
|
||||||
|
# TODO - It should be possible to set the IPC path with explicit parameters:
|
||||||
|
#
|
||||||
|
# ./test/soltest --ipc /tmp/test/geth.ipc
|
||||||
|
#
|
||||||
|
# But that doesn't work on macOS, so we're just using the cruder approach of
|
||||||
|
# using an environment variable. That works on Linux and macOS. We will
|
||||||
|
# need to check if this command-line support works for Windows too, when we
|
||||||
|
# have implemented IPC Sockets support at all for Windows.
|
||||||
|
export ETH_TEST_IPC=/tmp/test/geth.ipc
|
||||||
|
"$REPO_ROOT"/build/test/soltest
|
||||||
|
ERROR_CODE=$?
|
||||||
|
pkill eth || true
|
||||||
|
sleep 4
|
||||||
|
pgrep eth && pkill -9 eth || true
|
||||||
|
exit $ERROR_CODE
|
130
scripts/travis-emscripten/build_emscripten.sh
Executable file
130
scripts/travis-emscripten/build_emscripten.sh
Executable file
@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# This script builds the solidity binary using Emscripten.
|
||||||
|
# Emscripten is a way to compile C/C++ to JavaScript.
|
||||||
|
#
|
||||||
|
# http://kripken.github.io/emscripten-site/
|
||||||
|
#
|
||||||
|
# First run install_dep.sh OUTSIDE of docker and then
|
||||||
|
# run this script inside a docker image trzeci/emscripten
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# http://solidity.readthedocs.io/
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
# We need git for extracting the commit hash
|
||||||
|
apt-get update
|
||||||
|
apt-get -y install git-core
|
||||||
|
|
||||||
|
export WORKSPACE=/src
|
||||||
|
|
||||||
|
# CryptoPP
|
||||||
|
echo -en 'travis_fold:start:compiling_cryptopp\\r'
|
||||||
|
cd "$WORKSPACE/cryptopp"
|
||||||
|
# if .git exists, it is a fresh checkout, otherwise it comes from the cache
|
||||||
|
# and is already compiled
|
||||||
|
test -e .git && (
|
||||||
|
emcmake cmake -DCRYPTOPP_LIBRARY_TYPE=STATIC -DCRYPTOPP_RUNTIME_TYPE=STATIC && emmake make -j 4
|
||||||
|
ln -s . src/cryptopp || true
|
||||||
|
rm -rf .git
|
||||||
|
)
|
||||||
|
echo -en 'travis_fold:end:compiling_cryptopp\\r'
|
||||||
|
|
||||||
|
# Json-CPP
|
||||||
|
echo -en 'travis_fold:start:compiling_jsoncpp\\r'
|
||||||
|
cd "$WORKSPACE/jsoncpp"
|
||||||
|
# if .git exists, it is a fresh checkout, otherwise it comes from the cache
|
||||||
|
# and is already compiled
|
||||||
|
test -e .git && (
|
||||||
|
emcmake cmake -DJSONCPP_LIB_BUILD_STATIC=ON -DJSONCPP_LIB_BUILD_SHARED=OFF \
|
||||||
|
-DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF \
|
||||||
|
-G "Unix Makefiles" .
|
||||||
|
emmake make -j 4
|
||||||
|
rm -rf .git
|
||||||
|
)
|
||||||
|
echo -en 'travis_fold:end:compiling_jsoncpp\\r'
|
||||||
|
|
||||||
|
# Boost
|
||||||
|
echo -en 'travis_fold:start:compiling_boost\\r'
|
||||||
|
cd "$WORKSPACE"/boost_1_57_0
|
||||||
|
# if b2 exists, it is a fresh checkout, otherwise it comes from the cache
|
||||||
|
# and is already compiled
|
||||||
|
test -e b2 && (
|
||||||
|
sed -i 's|using gcc ;|using gcc : : /usr/local/bin/em++ ;|g' ./project-config.jam
|
||||||
|
sed -i 's|$(archiver\[1\])|/usr/local/bin/emar|g' ./tools/build/src/tools/gcc.jam
|
||||||
|
sed -i 's|$(ranlib\[1\])|/usr/local/bin/emranlib|g' ./tools/build/src/tools/gcc.jam
|
||||||
|
./b2 link=static variant=release threading=single runtime-link=static \
|
||||||
|
thread system regex date_time chrono filesystem unit_test_framework program_options random
|
||||||
|
find . -name 'libboost*.a' -exec cp {} . \;
|
||||||
|
rm -rf b2 libs doc tools more bin.v2 status
|
||||||
|
)
|
||||||
|
echo -en 'travis_fold:end:compiling_boost\\r'
|
||||||
|
|
||||||
|
# Build dependent components and solidity itself
|
||||||
|
echo -en 'travis_fold:start:compiling_solidity\\r'
|
||||||
|
cd $WORKSPACE
|
||||||
|
mkdir -p build-emscripten
|
||||||
|
cd build-emscripten
|
||||||
|
emcmake cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DEMSCRIPTEN=1 \
|
||||||
|
-DCMAKE_CXX_COMPILER=em++ \
|
||||||
|
-DCMAKE_C_COMPILER=emcc \
|
||||||
|
-DBoost_FOUND=1 \
|
||||||
|
-DBoost_USE_STATIC_LIBS=1 \
|
||||||
|
-DBoost_USE_STATIC_RUNTIME=1 \
|
||||||
|
-DBoost_INCLUDE_DIR="$WORKSPACE"/boost_1_57_0/ \
|
||||||
|
-DBoost_CHRONO_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_chrono.a \
|
||||||
|
-DBoost_CHRONO_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_chrono.a \
|
||||||
|
-DBoost_DATE_TIME_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_date_time.a \
|
||||||
|
-DBoost_DATE_TIME_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_date_time.a \
|
||||||
|
-DBoost_FILESYSTEM_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_filesystem.a \
|
||||||
|
-DBoost_FILESYSTEM_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_filesystem.a \
|
||||||
|
-DBoost_PROGRAM_OPTIONS_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_program_options.a \
|
||||||
|
-DBoost_PROGRAM_OPTIONS_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_program_options.a \
|
||||||
|
-DBoost_RANDOM_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_random.a \
|
||||||
|
-DBoost_RANDOM_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_random.a \
|
||||||
|
-DBoost_REGEX_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_regex.a \
|
||||||
|
-DBoost_REGEX_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_regex.a \
|
||||||
|
-DBoost_SYSTEM_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_system.a \
|
||||||
|
-DBoost_SYSTEM_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_system.a \
|
||||||
|
-DBoost_THREAD_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_thread.a \
|
||||||
|
-DBoost_THREAD_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_thread.a \
|
||||||
|
-DBoost_UNIT_TEST_FRAMEWORK_LIBRARY="$WORKSPACE"/boost_1_57_0/libboost_unit_test_framework.a \
|
||||||
|
-DBoost_UNIT_TEST_FRAMEWORK_LIBRARIES="$WORKSPACE"/boost_1_57_0/libboost_unit_test_framework.a \
|
||||||
|
-DJSONCPP_LIBRARY="$WORKSPACE"/jsoncpp/src/lib_json/libjsoncpp.a \
|
||||||
|
-DJSONCPP_INCLUDE_DIR="$WORKSPACE"/jsoncpp/include/ \
|
||||||
|
-DCRYPTOPP_LIBRARY="$WORKSPACE"/cryptopp/src/libcryptlib.a \
|
||||||
|
-DCRYPTOPP_INCLUDE_DIR="$WORKSPACE"/cryptopp/src/ \
|
||||||
|
-DDev_DEVCORE_LIBRARY="$WORKSPACE"/solidity/build/libdevcore/libdevcore.a \
|
||||||
|
-DEth_EVMASM_LIBRARY="$WORKSPACE"/solidity/build/libevmasm/libevmasm.a \
|
||||||
|
-DETHASHCL=0 -DEVMJIT=0 -DETH_STATIC=1 -DSOLIDITY=1 -DFATDB=0 -DTESTS=0 -DTOOLS=0 \
|
||||||
|
..
|
||||||
|
emmake make -j 4
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
cp build-emscripten/solc/soljson.js ./
|
||||||
|
|
||||||
|
echo -en 'travis_fold:end:compiling_solidity\\r'
|
BIN
scripts/travis-emscripten/deploy_key.enc
Normal file
BIN
scripts/travis-emscripten/deploy_key.enc
Normal file
Binary file not shown.
44
scripts/travis-emscripten/install_deps.sh
Executable file
44
scripts/travis-emscripten/install_deps.sh
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script for installing pre-requisite packages for building solidity
|
||||||
|
# using Emscripten on Ubuntu Trusty.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# http://solidity.readthedocs.io/
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -ev
|
||||||
|
|
||||||
|
echo -en 'travis_fold:start:installing_dependencies\\r'
|
||||||
|
test -e cryptopp -a -e cryptopp/src || git clone https://github.com/mmoss/cryptopp.git
|
||||||
|
test -e jsoncpp -a -e jsoncpp/include || git clone https://github.com/open-source-parsers/jsoncpp.git
|
||||||
|
test -e boost_1_57_0 -a -e boost_1_57_0/boost || (
|
||||||
|
wget 'http://downloads.sourceforge.net/project/boost/boost/'\
|
||||||
|
'1.57.0/boost_1_57_0.tar.bz2?r=http%3A%2F%2Fsourceforge.net%2F'\
|
||||||
|
'projects%2Fboost%2Ffiles%2Fboost%2F1.57.0%2F&ts=1421887207'\
|
||||||
|
-O - | tar xj
|
||||||
|
cd boost_1_57_0
|
||||||
|
./bootstrap.sh --with-toolset=gcc --with-libraries=thread,system,regex,date_time,chrono,filesystem,program_options,random
|
||||||
|
)
|
||||||
|
cd ..
|
||||||
|
echo -en 'travis_fold:end:installing_dependencies\\r'
|
70
scripts/travis-emscripten/publish_binary.sh
Executable file
70
scripts/travis-emscripten/publish_binary.sh
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Bash script for publishing Solidity Emscripten binaries to Github.
|
||||||
|
#
|
||||||
|
# The results are committed to https://github.com/ethereum/solc-bin.
|
||||||
|
#
|
||||||
|
# The documentation for solidity is hosted at:
|
||||||
|
#
|
||||||
|
# http://solidity.readthedocs.io/
|
||||||
|
#
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# This file is part of solidity.
|
||||||
|
#
|
||||||
|
# solidity is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# solidity is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
# (c) 2016 solidity contributors.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
VER=$(cat CMakeLists.txt | grep 'set(PROJECT_VERSION' | sed -e 's/.*set(PROJECT_VERSION "\(.*\)".*/\1/')
|
||||||
|
test -n "$VER"
|
||||||
|
VER="v$VER"
|
||||||
|
COMMIT=$(git rev-parse --short HEAD)
|
||||||
|
DATE=$(date --date="$(git log -1 --date=iso --format=%ad HEAD)" --utc +%F)
|
||||||
|
|
||||||
|
ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key"
|
||||||
|
ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv"
|
||||||
|
ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR}
|
||||||
|
ENCRYPTED_IV=${!ENCRYPTED_IV_VAR}
|
||||||
|
openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in scripts/travis-emscripten/deploy_key.enc -out deploy_key -d
|
||||||
|
chmod 600 deploy_key
|
||||||
|
eval `ssh-agent -s`
|
||||||
|
ssh-add deploy_key
|
||||||
|
|
||||||
|
git clone --depth 2 git@github.com:ethereum/solc-bin.git
|
||||||
|
cd solc-bin
|
||||||
|
git config user.name "travis"
|
||||||
|
git config user.email "chris@ethereum.org"
|
||||||
|
git checkout -B gh-pages origin/gh-pages
|
||||||
|
git clean -f -d -x
|
||||||
|
# We only want one release per day and we do not want to push the same commit twice.
|
||||||
|
if ls ./bin/soljson-"$VER-$DATE"-*.js ./bin/soljson-*-"$COMMIT.js" > /dev/null
|
||||||
|
then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
# This file is assumed to be the product of the build_emscripten.sh script.
|
||||||
|
cp ../soljson.js ./bin/"soljson-$VER-$DATE-$COMMIT.js"
|
||||||
|
./update-index.sh
|
||||||
|
cd bin
|
||||||
|
LATEST=$(ls -r soljson-v* | head -n 1)
|
||||||
|
cp "$LATEST" soljson-latest.js
|
||||||
|
cp soljson-latest.js ../soljson.js
|
||||||
|
git add .
|
||||||
|
git add ../soljson.js
|
||||||
|
git commit -m "Added compiler version $LATEST"
|
||||||
|
git push origin gh-pages
|
||||||
|
fi
|
@ -668,7 +668,7 @@ void CommandLineInterface::handleCombinedJSON()
|
|||||||
if (requests.count("srcmap-runtime"))
|
if (requests.count("srcmap-runtime"))
|
||||||
{
|
{
|
||||||
auto map = m_compiler->runtimeSourceMapping(contractName);
|
auto map = m_compiler->runtimeSourceMapping(contractName);
|
||||||
contractData["srcmap"] = map ? *map : "";
|
contractData["srcmap-runtime"] = map ? *map : "";
|
||||||
}
|
}
|
||||||
if (requests.count("devdoc"))
|
if (requests.count("devdoc"))
|
||||||
contractData["devdoc"] = m_compiler->metadata(contractName, DocumentationType::NatspecDev);
|
contractData["devdoc"] = m_compiler->metadata(contractName, DocumentationType::NatspecDev);
|
||||||
|
@ -26,7 +26,7 @@ file(GLOB HEADERS "*.h" "*/*.h")
|
|||||||
set(EXECUTABLE soltest)
|
set(EXECUTABLE soltest)
|
||||||
eth_simple_add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
|
eth_simple_add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
|
||||||
|
|
||||||
eth_use(${EXECUTABLE} REQUIRED Solidity::solidity Eth::ethcore)
|
eth_use(${EXECUTABLE} REQUIRED Solidity::solidity)
|
||||||
|
|
||||||
include_directories(BEFORE ..)
|
include_directories(BEFORE ..)
|
||||||
target_link_libraries(${EXECUTABLE} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
|
target_link_libraries(${EXECUTABLE} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
|
||||||
|
@ -38,15 +38,25 @@ IPCSocket::IPCSocket(string const& _path): m_path(_path)
|
|||||||
BOOST_FAIL("Error opening IPC: socket path is too long!");
|
BOOST_FAIL("Error opening IPC: socket path is too long!");
|
||||||
|
|
||||||
struct sockaddr_un saun;
|
struct sockaddr_un saun;
|
||||||
|
memset(&saun, 0, sizeof(sockaddr_un));
|
||||||
saun.sun_family = AF_UNIX;
|
saun.sun_family = AF_UNIX;
|
||||||
strcpy(saun.sun_path, _path.c_str());
|
strcpy(saun.sun_path, _path.c_str());
|
||||||
|
|
||||||
|
// http://idletechnology.blogspot.ca/2011/12/unix-domain-sockets-on-osx.html
|
||||||
|
//
|
||||||
|
// SUN_LEN() might be optimal, but it seemingly affects the portability,
|
||||||
|
// with at least Android missing this macro. Just using the sizeof() for
|
||||||
|
// structure seemingly works, and would only have the side-effect of
|
||||||
|
// sending larger-than-required packets over the socket. Given that this
|
||||||
|
// code is only used for unit-tests, that approach seems simpler.
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
saun.sun_len = sizeof(struct sockaddr_un);
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
|
||||||
if ((m_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
if ((m_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||||
BOOST_FAIL("Error creating IPC socket object");
|
BOOST_FAIL("Error creating IPC socket object");
|
||||||
|
|
||||||
int len = sizeof(saun.sun_family) + strlen(saun.sun_path);
|
if (connect(m_socket, reinterpret_cast<struct sockaddr const*>(&saun), sizeof(struct sockaddr_un)) < 0)
|
||||||
|
|
||||||
if (connect(m_socket, reinterpret_cast<struct sockaddr const*>(&saun), len) < 0)
|
|
||||||
BOOST_FAIL("Error connecting to IPC socket: " << _path);
|
BOOST_FAIL("Error connecting to IPC socket: " << _path);
|
||||||
|
|
||||||
m_fp = fdopen(m_socket, "r");
|
m_fp = fdopen(m_socket, "r");
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <libdevcore/ABI.h>
|
||||||
#include <libdevcore/Hash.h>
|
#include <libdevcore/Hash.h>
|
||||||
#include <libethcore/ABI.h>
|
|
||||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -333,7 +333,7 @@ BOOST_AUTO_TEST_CASE(double_reserve_long)
|
|||||||
registrar.reserve(name);
|
registrar.reserve(name);
|
||||||
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
||||||
|
|
||||||
sendEther(account(1), u256(10) * eth::ether);
|
sendEther(account(1), u256(10) * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
registrar.reserve(name);
|
registrar.reserve(name);
|
||||||
BOOST_CHECK_EQUAL(registrar.owner(name), account(0));
|
BOOST_CHECK_EQUAL(registrar.owner(name), account(0));
|
||||||
@ -350,7 +350,7 @@ BOOST_AUTO_TEST_CASE(properties)
|
|||||||
for (string const& name: names)
|
for (string const& name: names)
|
||||||
{
|
{
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(count), u256(20) * eth::ether);
|
sendEther(account(count), u256(20) * ether);
|
||||||
m_sender = account(count);
|
m_sender = account(count);
|
||||||
auto sender = m_sender;
|
auto sender = m_sender;
|
||||||
addr += count;
|
addr += count;
|
||||||
@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(disown)
|
|||||||
BOOST_CHECK_EQUAL(registrar.name(u160(124)), name);
|
BOOST_CHECK_EQUAL(registrar.name(u160(124)), name);
|
||||||
|
|
||||||
// someone else tries disowning
|
// someone else tries disowning
|
||||||
sendEther(account(1), u256(10) * eth::ether);
|
sendEther(account(1), u256(10) * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
registrar.disown(name);
|
registrar.disown(name);
|
||||||
BOOST_CHECK_EQUAL(registrar.owner(name), account(0));
|
BOOST_CHECK_EQUAL(registrar.owner(name), account(0));
|
||||||
@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
|||||||
registrar.setNextValue(12);
|
registrar.setNextValue(12);
|
||||||
registrar.reserve(name);
|
registrar.reserve(name);
|
||||||
// another bid by someone else
|
// another bid by someone else
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
m_rpc.test_modifyTimestamp(startTime + 2 * m_biddingTime - 50);
|
m_rpc.test_modifyTimestamp(startTime + 2 * m_biddingTime - 50);
|
||||||
registrar.setNextValue(13);
|
registrar.setNextValue(13);
|
||||||
@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(auction_renewal)
|
|||||||
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
||||||
|
|
||||||
// try to re-register before interval end
|
// try to re-register before interval end
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
m_rpc.test_modifyTimestamp(currentTimestamp() + m_renewalInterval - 1);
|
m_rpc.test_modifyTimestamp(currentTimestamp() + m_renewalInterval - 1);
|
||||||
registrar.setNextValue(80);
|
registrar.setNextValue(80);
|
||||||
|
@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(double_reserve)
|
|||||||
BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
|
||||||
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(account(0), h256::AlignRight)));
|
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(account(0), h256::AlignRight)));
|
||||||
|
|
||||||
sendEther(account(1), 100 * eth::ether);
|
sendEther(account(1), 100 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs());
|
||||||
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(account(0), h256::AlignRight)));
|
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(account(0), h256::AlignRight)));
|
||||||
@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(properties)
|
|||||||
{
|
{
|
||||||
addr++;
|
addr++;
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(count), 100 * eth::ether);
|
sendEther(account(count), 100 * ether);
|
||||||
m_sender = account(count);
|
m_sender = account(count);
|
||||||
Address owner = m_sender;
|
Address owner = m_sender;
|
||||||
// setting by sender works
|
// setting by sender works
|
||||||
@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(properties)
|
|||||||
count++;
|
count++;
|
||||||
// but not by someone else
|
// but not by someone else
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(count), 100 * eth::ether);
|
sendEther(account(count), 100 * ether);
|
||||||
m_sender = account(count);
|
m_sender = account(count);
|
||||||
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(owner, h256::AlignRight)));
|
BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(owner, h256::AlignRight)));
|
||||||
BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), addr + 1, u256(name.length()), name) == encodeArgs());
|
BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), addr + 1, u256(name.length()), name) == encodeArgs());
|
||||||
|
@ -474,13 +474,13 @@ BOOST_AUTO_TEST_CASE(add_owners)
|
|||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(account(1), h256::AlignRight)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(account(1), h256::AlignRight)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(account(1), h256::AlignRight)) == encodeArgs(true));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(account(1), h256::AlignRight)) == encodeArgs(true));
|
||||||
// now let the new owner add someone
|
// now let the new owner add someone
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x13)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x13)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x13)) == encodeArgs(true));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x13)) == encodeArgs(true));
|
||||||
// and check that a non-owner cannot add a new owner
|
// and check that a non-owner cannot add a new owner
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(2), 10 * eth::ether);
|
sendEther(account(2), 10 * ether);
|
||||||
m_sender = account(2);
|
m_sender = account(2);
|
||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x20)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x20)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x20)) == encodeArgs(false));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x20)) == encodeArgs(false));
|
||||||
@ -559,17 +559,17 @@ BOOST_AUTO_TEST_CASE(multisig_value_transfer)
|
|||||||
// check that balance is and stays zero at destination address
|
// check that balance is and stays zero at destination address
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
auto ophash = callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00);
|
auto ophash = callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00);
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(2), 10 * eth::ether);
|
sendEther(account(2), 10 * ether);
|
||||||
m_sender = account(2);
|
m_sender = account(2);
|
||||||
callContractFunction("confirm(bytes32)", ophash);
|
callContractFunction("confirm(bytes32)", ophash);
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(3), 10 * eth::ether);
|
sendEther(account(3), 10 * ether);
|
||||||
m_sender = account(3);
|
m_sender = account(3);
|
||||||
callContractFunction("confirm(bytes32)", ophash);
|
callContractFunction("confirm(bytes32)", ophash);
|
||||||
// now it should go through
|
// now it should go through
|
||||||
@ -590,7 +590,7 @@ BOOST_AUTO_TEST_CASE(revoke_addOwner)
|
|||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false));
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false));
|
||||||
@ -598,12 +598,12 @@ BOOST_AUTO_TEST_CASE(revoke_addOwner)
|
|||||||
m_sender = deployer;
|
m_sender = deployer;
|
||||||
BOOST_REQUIRE(callContractFunction("revoke(bytes32)", opHash) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("revoke(bytes32)", opHash) == encodeArgs());
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(2), 10 * eth::ether);
|
sendEther(account(2), 10 * ether);
|
||||||
m_sender = account(2);
|
m_sender = account(2);
|
||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false));
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(3), 10 * eth::ether);
|
sendEther(account(3), 10 * ether);
|
||||||
m_sender = account(3);
|
m_sender = account(3);
|
||||||
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs());
|
||||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(true));
|
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(true));
|
||||||
@ -621,24 +621,24 @@ BOOST_AUTO_TEST_CASE(revoke_transaction)
|
|||||||
Address deployer = m_sender;
|
Address deployer = m_sender;
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
auto opHash = callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00);
|
auto opHash = callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00);
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(2), 10 * eth::ether);
|
sendEther(account(2), 10 * ether);
|
||||||
m_sender = account(2);
|
m_sender = account(2);
|
||||||
callContractFunction("confirm(bytes32)", opHash);
|
callContractFunction("confirm(bytes32)", opHash);
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
BOOST_REQUIRE(callContractFunction("revoke(bytes32)", opHash) == encodeArgs());
|
BOOST_REQUIRE(callContractFunction("revoke(bytes32)", opHash) == encodeArgs());
|
||||||
m_sender = deployer;
|
m_sender = deployer;
|
||||||
callContractFunction("confirm(bytes32)", opHash);
|
callContractFunction("confirm(bytes32)", opHash);
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(3), 10 * eth::ether);
|
sendEther(account(3), 10 * ether);
|
||||||
m_sender = account(3);
|
m_sender = account(3);
|
||||||
callContractFunction("confirm(bytes32)", opHash);
|
callContractFunction("confirm(bytes32)", opHash);
|
||||||
// now it should go through
|
// now it should go through
|
||||||
@ -659,7 +659,7 @@ BOOST_AUTO_TEST_CASE(daylimit)
|
|||||||
|
|
||||||
// try to send tx over daylimit
|
// try to send tx over daylimit
|
||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
m_sender = account(1);
|
m_sender = account(1);
|
||||||
BOOST_REQUIRE(
|
BOOST_REQUIRE(
|
||||||
callContractFunction("execute(address,uint256,bytes)", h256(0x05), 150, 0x60, 0x00) !=
|
callContractFunction("execute(address,uint256,bytes)", h256(0x05), 150, 0x60, 0x00) !=
|
||||||
@ -668,7 +668,7 @@ BOOST_AUTO_TEST_CASE(daylimit)
|
|||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
// try to send tx under daylimit by stranger
|
// try to send tx under daylimit by stranger
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(4), 10 * eth::ether);
|
sendEther(account(4), 10 * ether);
|
||||||
m_sender = account(4);
|
m_sender = account(4);
|
||||||
BOOST_REQUIRE(
|
BOOST_REQUIRE(
|
||||||
callContractFunction("execute(address,uint256,bytes)", h256(0x05), 90, 0x60, 0x00) ==
|
callContractFunction("execute(address,uint256,bytes)", h256(0x05), 90, 0x60, 0x00) ==
|
||||||
@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE(daylimit)
|
|||||||
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0);
|
||||||
// now send below limit by owner
|
// now send below limit by owner
|
||||||
m_sender = account(0);
|
m_sender = account(0);
|
||||||
sendEther(account(1), 10 * eth::ether);
|
sendEther(account(1), 10 * ether);
|
||||||
BOOST_REQUIRE(
|
BOOST_REQUIRE(
|
||||||
callContractFunction("execute(address,uint256,bytes)", h256(0x05), 90, 0x60, 0x00) ==
|
callContractFunction("execute(address,uint256,bytes)", h256(0x05), 90, 0x60, 0x00) ==
|
||||||
encodeArgs(u256(0))
|
encodeArgs(u256(0))
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||||
|
#include <libevmasm/EVMSchedule.h>
|
||||||
#include <libevmasm/GasMeter.h>
|
#include <libevmasm/GasMeter.h>
|
||||||
#include <libevmasm/KnownState.h>
|
#include <libevmasm/KnownState.h>
|
||||||
#include <libevmasm/PathGasMeter.h>
|
#include <libevmasm/PathGasMeter.h>
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
* Unit tests for the solidity expression compiler, testing the behaviour of the code.
|
* Unit tests for the solidity expression compiler, testing the behaviour of the code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
@ -2462,7 +2464,7 @@ BOOST_AUTO_TEST_CASE(use_std_lib)
|
|||||||
contract Icarus is mortal { }
|
contract Icarus is mortal { }
|
||||||
)";
|
)";
|
||||||
m_addStandardSources = true;
|
m_addStandardSources = true;
|
||||||
u256 amount(130 * eth::ether);
|
u256 amount(130 * ether);
|
||||||
compileAndRun(sourceCode, amount, "Icarus");
|
compileAndRun(sourceCode, amount, "Icarus");
|
||||||
u256 balanceBefore = balanceAt(m_sender);
|
u256 balanceBefore = balanceAt(m_sender);
|
||||||
BOOST_CHECK(callContractFunction("kill()") == bytes());
|
BOOST_CHECK(callContractFunction("kill()") == bytes());
|
||||||
@ -5921,9 +5923,9 @@ BOOST_AUTO_TEST_CASE(version_stamp_for_libraries)
|
|||||||
m_optimize = true;
|
m_optimize = true;
|
||||||
bytes runtimeCode = compileAndRun(sourceCode, 0, "lib");
|
bytes runtimeCode = compileAndRun(sourceCode, 0, "lib");
|
||||||
BOOST_CHECK(runtimeCode.size() >= 8);
|
BOOST_CHECK(runtimeCode.size() >= 8);
|
||||||
BOOST_CHECK_EQUAL(runtimeCode[0], int(eth::Instruction::PUSH6)); // might change once we switch to 1.x.x
|
BOOST_CHECK_EQUAL(runtimeCode[0], int(Instruction::PUSH6)); // might change once we switch to 1.x.x
|
||||||
BOOST_CHECK_EQUAL(runtimeCode[1], 3); // might change once we switch away from x.3.x
|
BOOST_CHECK_EQUAL(runtimeCode[1], 3); // might change once we switch away from x.3.x
|
||||||
BOOST_CHECK_EQUAL(runtimeCode[7], int(eth::Instruction::POP));
|
BOOST_CHECK_EQUAL(runtimeCode[7], int(Instruction::POP));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(contract_binary_dependencies)
|
BOOST_AUTO_TEST_CASE(contract_binary_dependencies)
|
||||||
@ -6837,6 +6839,20 @@ BOOST_AUTO_TEST_CASE(skip_dynamic_types_for_structs)
|
|||||||
BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(2), u256(6)));
|
BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(2), u256(6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(create_dynamic_array_with_zero_length)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function f() returns (uint) {
|
||||||
|
var a = new uint[][](0);
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "C");
|
||||||
|
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7)));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,21 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <boost/test/framework.hpp>
|
#include <boost/test/framework.hpp>
|
||||||
|
#include <libdevcore/CommonIO.h>
|
||||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace dev::solidity;
|
using namespace dev::solidity;
|
||||||
using namespace dev::solidity::test;
|
using namespace dev::solidity::test;
|
||||||
|
|
||||||
|
namespace // anonymous
|
||||||
|
{
|
||||||
|
h256 const EmptyTrie("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
|
||||||
|
}
|
||||||
|
|
||||||
string getIPCSocketPath()
|
string getIPCSocketPath()
|
||||||
{
|
{
|
||||||
string ipcPath;
|
string ipcPath;
|
||||||
@ -56,9 +64,6 @@ ExecutionFramework::ExecutionFramework() :
|
|||||||
m_rpc(RPCSession::instance(getIPCSocketPath())),
|
m_rpc(RPCSession::instance(getIPCSocketPath())),
|
||||||
m_sender(m_rpc.account(0))
|
m_sender(m_rpc.account(0))
|
||||||
{
|
{
|
||||||
if (g_logVerbosity != -1)
|
|
||||||
g_logVerbosity = 0;
|
|
||||||
|
|
||||||
m_rpc.test_rewindToBlock(0);
|
m_rpc.test_rewindToBlock(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,25 +22,33 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <functional>
|
||||||
#include <tuple>
|
|
||||||
#include <fstream>
|
|
||||||
#include "../TestHelper.h"
|
#include "../TestHelper.h"
|
||||||
#include "../RPCSession.h"
|
#include "../RPCSession.h"
|
||||||
#include <libethcore/ABI.h>
|
|
||||||
#include <libethcore/SealEngine.h>
|
#include <libdevcore/ABI.h>
|
||||||
#include <libethereum/State.h>
|
#include <libdevcore/FixedHash.h>
|
||||||
#include <libethereum/Executive.h>
|
#include <libevmasm/Instruction.h>
|
||||||
#include <libethereum/ChainParams.h>
|
|
||||||
#include <libsolidity/interface/CompilerStack.h>
|
#include <libsolidity/interface/CompilerStack.h>
|
||||||
#include <libsolidity/interface/Exceptions.h>
|
#include <libsolidity/interface/Exceptions.h>
|
||||||
#include <libethcore/BasicAuthority.h>
|
|
||||||
#include <libethcore/SealEngine.h>
|
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
/// An Ethereum address: 20 bytes.
|
||||||
|
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
|
||||||
|
using Address = h160;
|
||||||
|
|
||||||
|
// The various denominations; here for ease of use where needed within code.
|
||||||
|
static const u256 ether = exp10<18>();
|
||||||
|
static const u256 finney = exp10<15>();
|
||||||
|
static const u256 szabo = exp10<12>();
|
||||||
|
static const u256 shannon = exp10<9>();
|
||||||
|
static const u256 wei = exp10<0>();
|
||||||
|
|
||||||
namespace test
|
namespace test
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -275,8 +283,7 @@ protected:
|
|||||||
dev::solidity::CompilerStack m_compiler;
|
dev::solidity::CompilerStack m_compiler;
|
||||||
Address m_sender;
|
Address m_sender;
|
||||||
Address m_contractAddress;
|
Address m_contractAddress;
|
||||||
eth::EnvInfo m_envInfo;
|
u256 const m_gasPrice = 100 * szabo;
|
||||||
u256 const m_gasPrice = 100 * eth::szabo;
|
|
||||||
u256 const m_gas = 100000000;
|
u256 const m_gas = 100000000;
|
||||||
bytes m_output;
|
bytes m_output;
|
||||||
std::vector<LogEntry> m_logs;
|
std::vector<LogEntry> m_logs;
|
||||||
|
@ -79,6 +79,8 @@ public:
|
|||||||
bytes nonOptimizedOutput = callContractFunction(_sig, _arguments...);
|
bytes nonOptimizedOutput = callContractFunction(_sig, _arguments...);
|
||||||
m_contractAddress = m_optimizedContract;
|
m_contractAddress = m_optimizedContract;
|
||||||
bytes optimizedOutput = callContractFunction(_sig, _arguments...);
|
bytes optimizedOutput = callContractFunction(_sig, _arguments...);
|
||||||
|
BOOST_CHECK_MESSAGE(!optimizedOutput.empty(), "No optimized output for " + _sig);
|
||||||
|
BOOST_CHECK_MESSAGE(!nonOptimizedOutput.empty(), "No un-optimized output for " + _sig);
|
||||||
BOOST_CHECK_MESSAGE(nonOptimizedOutput == optimizedOutput, "Computed values do not match."
|
BOOST_CHECK_MESSAGE(nonOptimizedOutput == optimizedOutput, "Computed values do not match."
|
||||||
"\nNon-Optimized: " + toHex(nonOptimizedOutput) +
|
"\nNon-Optimized: " + toHex(nonOptimizedOutput) +
|
||||||
"\nOptimized: " + toHex(optimizedOutput));
|
"\nOptimized: " + toHex(optimizedOutput));
|
||||||
@ -176,7 +178,7 @@ BOOST_AUTO_TEST_CASE(identities)
|
|||||||
}
|
}
|
||||||
})";
|
})";
|
||||||
compileBothVersions(sourceCode);
|
compileBothVersions(sourceCode);
|
||||||
compareVersions("f(uint256)", u256(0x12334664));
|
compareVersions("f(int256)", u256(0x12334664));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(unused_expressions)
|
BOOST_AUTO_TEST_CASE(unused_expressions)
|
||||||
@ -230,6 +232,7 @@ BOOST_AUTO_TEST_CASE(array_copy)
|
|||||||
bytes2[] data1;
|
bytes2[] data1;
|
||||||
bytes5[] data2;
|
bytes5[] data2;
|
||||||
function f(uint x) returns (uint l, uint y) {
|
function f(uint x) returns (uint l, uint y) {
|
||||||
|
data1.length = msg.data.length;
|
||||||
for (uint i = 0; i < msg.data.length; ++i)
|
for (uint i = 0; i < msg.data.length; ++i)
|
||||||
data1[i] = msg.data[i];
|
data1[i] = msg.data[i];
|
||||||
data2 = data1;
|
data2 = data1;
|
||||||
@ -241,7 +244,7 @@ BOOST_AUTO_TEST_CASE(array_copy)
|
|||||||
compileBothVersions(sourceCode);
|
compileBothVersions(sourceCode);
|
||||||
compareVersions("f(uint256)", 0);
|
compareVersions("f(uint256)", 0);
|
||||||
compareVersions("f(uint256)", 10);
|
compareVersions("f(uint256)", 10);
|
||||||
compareVersions("f(uint256)", 36);
|
compareVersions("f(uint256)", 35);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_calls)
|
BOOST_AUTO_TEST_CASE(function_calls)
|
||||||
@ -279,6 +282,8 @@ BOOST_AUTO_TEST_CASE(storage_write_in_loops)
|
|||||||
compareVersions("f(uint256)", 36);
|
compareVersions("f(uint256)", 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test disabled with https://github.com/ethereum/solidity/pull/762
|
||||||
|
// Information in joining branches is not retained anymore.
|
||||||
BOOST_AUTO_TEST_CASE(retain_information_in_branches)
|
BOOST_AUTO_TEST_CASE(retain_information_in_branches)
|
||||||
{
|
{
|
||||||
// This tests that the optimizer knows that we already have "z == sha3(y)" inside both branches.
|
// This tests that the optimizer knows that we already have "z == sha3(y)" inside both branches.
|
||||||
@ -312,7 +317,8 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches)
|
|||||||
if (_instr == Instruction::SHA3)
|
if (_instr == Instruction::SHA3)
|
||||||
numSHA3s++;
|
numSHA3s++;
|
||||||
});
|
});
|
||||||
BOOST_CHECK_EQUAL(1, numSHA3s);
|
// TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE
|
||||||
|
// BOOST_CHECK_EQUAL(1, numSHA3s);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(store_tags_as_unions)
|
BOOST_AUTO_TEST_CASE(store_tags_as_unions)
|
||||||
@ -346,7 +352,7 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions)
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
compileBothVersions(sourceCode);
|
compileBothVersions(sourceCode);
|
||||||
compareVersions("f()", 7, "abc");
|
compareVersions("f(uint256,bytes32)", 7, "abc");
|
||||||
|
|
||||||
m_optimize = true;
|
m_optimize = true;
|
||||||
bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test");
|
bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test");
|
||||||
@ -1174,6 +1180,64 @@ BOOST_AUTO_TEST_CASE(computing_constants)
|
|||||||
) == optimizedBytecode.cend());
|
) == optimizedBytecode.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(inconsistency)
|
||||||
|
{
|
||||||
|
// This is a test of a bug in the optimizer.
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract Inconsistency {
|
||||||
|
struct Value {
|
||||||
|
uint badnum;
|
||||||
|
uint number;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Container {
|
||||||
|
uint[] valueIndices;
|
||||||
|
Value[] values;
|
||||||
|
}
|
||||||
|
|
||||||
|
Container[] containers;
|
||||||
|
uint[] valueIndices;
|
||||||
|
uint INDEX_ZERO = 0;
|
||||||
|
uint debug;
|
||||||
|
|
||||||
|
// Called with params: containerIndex=0, valueIndex=0
|
||||||
|
function levelIII(uint containerIndex, uint valueIndex) private {
|
||||||
|
Container container = containers[containerIndex];
|
||||||
|
Value value = container.values[valueIndex];
|
||||||
|
debug = container.valueIndices[value.number];
|
||||||
|
}
|
||||||
|
function levelII() private {
|
||||||
|
for (uint i = 0; i < valueIndices.length; i++) {
|
||||||
|
levelIII(INDEX_ZERO, valueIndices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function trigger() public returns (uint) {
|
||||||
|
containers.length++;
|
||||||
|
Container container = containers[0];
|
||||||
|
|
||||||
|
container.values.push(Value({
|
||||||
|
badnum: 9000,
|
||||||
|
number: 0
|
||||||
|
}));
|
||||||
|
|
||||||
|
container.valueIndices.length++;
|
||||||
|
valueIndices.length++;
|
||||||
|
|
||||||
|
levelII();
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DoNotCallButDoNotDelete() public {
|
||||||
|
levelII();
|
||||||
|
levelIII(1, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileBothVersions(sourceCode);
|
||||||
|
compareVersions("trigger()");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user