Browse Source

Merge branch 'release-poc-3'

cl-refactor
Gav Wood 11 years ago
parent
commit
d1706f4ee4
  1. 4
      CMakeLists.txt
  2. 68
      Ethereum.sln
  3. 20
      README.md
  4. 11
      TODO
  5. 450
      alethzero/Main.ui
  6. 477
      alethzero/MainWin.cpp
  7. 32
      alethzero/MainWin.h
  8. 2
      alethzero/main.cpp
  9. 128
      eth/main.cpp
  10. 10
      json_spirit/CMakeLists.txt
  11. 18
      json_spirit/json_spirit.h
  12. 209
      json_spirit/json_spirit.vcproj
  13. 54
      json_spirit/json_spirit_error_position.h
  14. 137
      json_spirit/json_spirit_reader.cpp
  15. 62
      json_spirit/json_spirit_reader.h
  16. 612
      json_spirit/json_spirit_reader_template.h
  17. 70
      json_spirit/json_spirit_stream_reader.h
  18. 61
      json_spirit/json_spirit_utils.h
  19. 8
      json_spirit/json_spirit_value.cpp
  20. 532
      json_spirit/json_spirit_value.h
  21. 95
      json_spirit/json_spirit_writer.cpp
  22. 50
      json_spirit/json_spirit_writer.h
  23. 248
      json_spirit/json_spirit_writer_template.h
  24. 27
      libethereum/AddressState.h
  25. 41
      libethereum/BlockChain.cpp
  26. 12
      libethereum/BlockChain.h
  27. 4
      libethereum/BlockInfo.cpp
  28. 79
      libethereum/Client.cpp
  29. 40
      libethereum/Client.h
  30. 28
      libethereum/Common.cpp
  31. 269
      libethereum/Common.h
  32. 21
      libethereum/Dagger.cpp
  33. 23
      libethereum/Dagger.h
  34. 16
      libethereum/Exceptions.h
  35. 76
      libethereum/ExtVMFace.h
  36. 49
      libethereum/FeeStructure.cpp
  37. 43
      libethereum/FeeStructure.h
  38. 2
      libethereum/FileSystem.cpp
  39. 577
      libethereum/Instruction.cpp
  40. 168
      libethereum/Instruction.h
  41. 19
      libethereum/LibEthereum.props
  42. 32
      libethereum/LibEthereum.vcxproj.filters
  43. 63
      libethereum/PeerNetwork.cpp
  44. 34
      libethereum/PeerNetwork.h
  45. 26
      libethereum/RLP.cpp
  46. 7
      libethereum/RLP.h
  47. 722
      libethereum/State.cpp
  48. 162
      libethereum/State.h
  49. 12
      libethereum/Transaction.cpp
  50. 14
      libethereum/Transaction.h
  51. 6
      libethereum/TrieCommon.cpp
  52. 4
      libethereum/TrieCommon.h
  53. 21
      libethereum/TrieDB.h
  54. 14
      libethereum/UPnP.cpp
  55. 4
      libethereum/UPnP.h
  56. 60
      libethereum/VM.cpp
  57. 594
      libethereum/VM.h
  58. 14
      release.sh
  59. 2
      secp256k1/impl/num.h
  60. 212
      secp256k1/impl/num_boost.h
  61. 2
      secp256k1/num.h
  62. 12
      secp256k1/num_boost.h
  63. 8
      secp256k1/secp256k1.c
  64. 470
      secp256k1/tests.c
  65. 8
      test/crypto.cpp
  66. 10
      test/dagger.cpp
  67. 4
      test/main.cpp
  68. 7
      test/peer.cpp
  69. 3
      test/state.cpp
  70. 15
      test/trie.cpp
  71. 451
      test/vm.cpp
  72. 84
      test/vmtests.json
  73. 212
      windows/Alethzero.vcxproj
  74. 28
      windows/Alethzero.vcxproj.filters
  75. 18
      windows/CopyBinary.props
  76. 121
      windows/Ethereum.sln
  77. 48
      windows/Ethereum.vcxproj
  78. 176
      windows/LibCryptoPP.vcxproj
  79. 31
      windows/LibEthereum.props
  80. 218
      windows/LibEthereum.vcxproj
  81. 63
      windows/LibEthereum.vcxproj.filters
  82. 223
      windows/LibLevelDB.vcxproj
  83. 246
      windows/LibLevelDB.vcxproj.filters
  84. 184
      windows/LibMiniUPnPc.vcxproj
  85. 110
      windows/LibSecp256k1.vcxproj
  86. 71
      windows/LibSecp256k1.vcxproj.filters
  87. 181
      windows/TestEthereum.vcxproj
  88. 27
      windows/TestEthereum.vcxproj.filters
  89. 63
      windows/TestSecp256k1.vcxproj
  90. 38
      windows/UseQt.props
  91. 72
      windows/WinMain.cpp
  92. 160
      windows/bootstrap.sh
  93. 14
      windows/compile_ethereum.bat
  94. 41
      windows/compile_qt.bat
  95. 23
      windows/include/LibLevelDB/port/port.h
  96. 0
      windows/include/LibLevelDB/unistd.h
  97. 14
      windows/include/LibMiniUPnPc/miniupnpcstrings.h
  98. 38
      windows/moc.lua
  99. 2
      windows/qt_plugin_import.cpp
  100. 21
      windows/stdafx.cpp

4
CMakeLists.txt

@ -5,7 +5,6 @@ set(CMAKE_AUTOMOC ON)
cmake_policy(SET CMP0015 NEW)
set(ETH_VERSION 0.2.9)
set(ETH_BUILD_TYPE ${CMAKE_BUILD_TYPE})
# Default HEADLESS to 0.
@ -36,6 +35,8 @@ if ("${TARGET_PLATFORM}" STREQUAL "w64")
/usr/x86_64-w64-mingw32
)
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
@ -65,7 +66,6 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
add_definitions("-DETH_VERSION=${ETH_VERSION}")
add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}")
add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}")
#set(CMAKE_CXX_FLAGS, "${CMAKE_CXX_FLAGS} -DETH_VERSION=${ETH_VERSION} -DETH_BUILD_TYPE=${ETH_BUILD_TYPE} -DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}")

68
Ethereum.sln

@ -1,68 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibEthereum", "libethereum\LibEthereum.vcxproj", "{7050C7CF-7551-48BE-8E57-92235906C13A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestMining", "test\TestMining.vcxproj", "{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "test\Test.vcxproj", "{3F3E389B-88DE-41D5-A73B-4F6036E18B36}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "..\cryptopp562\cryptlib.vcxproj", "{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ethereum", "eth\Ethereum.vcxproj", "{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7050C7CF-7551-48BE-8E57-92235906C13A}.Debug|Win32.ActiveCfg = Debug|Win32
{7050C7CF-7551-48BE-8E57-92235906C13A}.Debug|Win32.Build.0 = Debug|Win32
{7050C7CF-7551-48BE-8E57-92235906C13A}.Debug|x64.ActiveCfg = Debug|x64
{7050C7CF-7551-48BE-8E57-92235906C13A}.Debug|x64.Build.0 = Debug|x64
{7050C7CF-7551-48BE-8E57-92235906C13A}.Release|Win32.ActiveCfg = Release|Win32
{7050C7CF-7551-48BE-8E57-92235906C13A}.Release|Win32.Build.0 = Release|Win32
{7050C7CF-7551-48BE-8E57-92235906C13A}.Release|x64.ActiveCfg = Release|x64
{7050C7CF-7551-48BE-8E57-92235906C13A}.Release|x64.Build.0 = Release|x64
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Debug|Win32.ActiveCfg = Debug|Win32
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Debug|Win32.Build.0 = Debug|Win32
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Debug|x64.ActiveCfg = Debug|x64
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Debug|x64.Build.0 = Debug|x64
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Release|Win32.ActiveCfg = Release|Win32
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Release|Win32.Build.0 = Release|Win32
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Release|x64.ActiveCfg = Release|x64
{02DC8A9B-DEF7-403B-8AE3-EF9680937D96}.Release|x64.Build.0 = Release|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|Win32.ActiveCfg = Debug|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|Win32.Build.0 = Debug|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|x64.ActiveCfg = Debug|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|x64.Build.0 = Debug|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|Win32.ActiveCfg = Release|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|Win32.Build.0 = Release|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|x64.ActiveCfg = Release|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|x64.Build.0 = Release|x64
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Debug|Win32.ActiveCfg = Debug|Win32
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Debug|Win32.Build.0 = Debug|Win32
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Debug|x64.ActiveCfg = Debug|x64
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Debug|x64.Build.0 = Debug|x64
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Release|Win32.ActiveCfg = Release|Win32
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Release|Win32.Build.0 = Release|Win32
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Release|x64.ActiveCfg = Release|x64
{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}.Release|x64.Build.0 = Release|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|Win32.ActiveCfg = Debug|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|Win32.Build.0 = Debug|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|x64.ActiveCfg = Debug|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|x64.Build.0 = Debug|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|Win32.ActiveCfg = Release|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|Win32.Build.0 = Release|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|x64.ActiveCfg = Release|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

20
README.md

@ -1,21 +1,27 @@
# cpp-ethereum
## Ethereum C++ Client.
Ethereum C++ Client.
By Gav Wood, 2014.
Gav Wood, 2014.
Based on a design by Vitalik Buterin.
## Building
Contributors, builders and testers include Eric Lombrozo (cross-compilation), Tim Hughes (MSVC compilation & Dagger testing), Alex Leverington (Clang & Mac building), Marko Simovic (CI) and several others.
### Building
See [Build Instructions](https://github.com/ethereum/cpp-ethereum/wiki/Build-Instructions) and [Compatibility Info and Build Tips](https://github.com/ethereum/cpp-ethereum/wiki/Compatibility-Info-and-Build-Tips).
## Yet To Do
### Testing
To run the tests, make sure you clone the tests repository from github.com/ethereum to tests is a sibling to cpp-ethereum-build.
### Yet To Do
See [TODO](TODO)
## License
### License
See [LICENSE](LICENSE)
## Contributing
### Contributing
Please read [CodingStandards.txt](CodingStandards.txt) thoroughly before making alterations to the code base. Please do *NOT* use an editor that automatically reformats whitespace away from astylerc or the formatting guidelines as described in [CodingStandards.txt](CodingStandards.txt).

11
TODO

@ -9,6 +9,7 @@ Crypto stuff:
Network:
- *** Exponential backoff on bad connection.
- *** Handle exception when no network.
- NotInChain will be very bad for new peers - it'll run through until the genesis.
- Check how many it has first.
- Crypto on network - use id as public key?
@ -18,14 +19,15 @@ Network:
- Solid communications?
- Strategy for peer suggestion?
Cleanups & caching
- All caches should flush unused data (I'm looking at you, BlockChain) to avoid memory overload.
- State DB should keep only last few N blocks worth of nodes (except for restore points - configurable, defaults to every 30000th block - all blocks that are restore points should be stored so their stateRoots are known good).
THREAD-SAFETY
- BlockChain
- TransactionQueue
- State
CLI client
- Implement CLI option "--help".
General:
- Better logging.
- Colours.
@ -43,11 +45,10 @@ GUI
- Make address/block chain list model-based, JIT populated.
- Make everything else model-based
- Qt/QML class.
- Turn on/off debug channels.
For PoC3:
- Shared contract acceptence tests.
- Use mining state for nonce.
BUG: need to discard transactions if nonce too old, even when not mining.
### Marko

450
alethzero/Main.ui

@ -6,33 +6,38 @@
<rect>
<x>0</x>
<y>0</y>
<width>1112</width>
<height>766</height>
<width>1504</width>
<height>798</height>
</rect>
</property>
<property name="windowTitle">
<string>AlethZero Ethereum Client</string>
</property>
<property name="dockNestingEnabled">
<bool>true</bool>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs</set>
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs</set>
</property>
<property name="sizeGripEnabled" stdset="0">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>4</number>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="margin">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="transactions">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
<widget class="QWidget" name="widget" native="true"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
@ -51,7 +56,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="blockChain">
<widget class="QLabel" name="blockCount">
<property name="text">
<string>1 block</string>
</property>
@ -66,8 +71,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1112</width>
<height>28</height>
<width>1504</width>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@ -81,14 +86,16 @@
<string>&amp;Network</string>
</property>
<addaction name="upnp"/>
<addaction name="net"/>
<addaction name="connect"/>
</widget>
<widget class="QMenu" name="menu_Tools">
<property name="title">
<string>&amp;Tools</string>
<string>T&amp;ools</string>
</property>
<addaction name="mine"/>
<addaction name="create"/>
<addaction name="preview"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
@ -114,11 +121,23 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="accounts">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -139,7 +158,16 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -148,6 +176,9 @@
<enum>Qt::Vertical</enum>
</property>
<widget class="QListWidget" name="peers">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -180,21 +211,30 @@
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Ideal Peers</string>
<string>Ideal &amp;Peers</string>
</property>
<property name="buddy">
<cstring>idealPeers</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Client Name</string>
<string>&amp;Client Name</string>
</property>
<property name="buddy">
<cstring>clientName</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Listen on</string>
<string>&amp;Listen on</string>
</property>
<property name="buddy">
<cstring>port</cstring>
</property>
</widget>
</item>
@ -224,7 +264,16 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -235,6 +284,9 @@
<pointsize>12</pointsize>
</font>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -274,11 +326,23 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="transactionQueue">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -299,6 +363,7 @@
</attribute>
<addaction name="net"/>
<addaction name="connect"/>
<addaction name="preview"/>
<addaction name="mine"/>
</widget>
<widget class="QDockWidget" name="dockWidget_5">
@ -310,8 +375,8 @@
</property>
<property name="minimumSize">
<size>
<width>408</width>
<height>251</height>
<width>442</width>
<height>360</height>
</size>
</property>
<property name="features">
@ -325,69 +390,82 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>4</number>
</property>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label5_2">
<property name="text">
<string>Amount</string>
</property>
</widget>
</item>
<item row="1" column="3" colspan="2">
<widget class="QComboBox" name="valueUnits"/>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="value">
<property name="suffix">
<string/>
<item row="0" column="0">
<widget class="QLabel" name="label5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>430000000</number>
<property name="text">
<string>&amp;To</string>
</property>
<property name="value">
<number>1000</number>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="label5_2">
<property name="text">
<string>Data</string>
<string>&amp;Amount</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
<property name="buddy">
<cstring>value</cstring>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label5">
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>To</string>
<string>&amp;Data</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="3" column="0" colspan="5">
<widget class="QPlainTextEdit" name="data"/>
<item row="4" column="0" colspan="4">
<widget class="QSplitter" name="splitter_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QPlainTextEdit" name="data"/>
<widget class="QPlainTextEdit" name="code">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item row="4" column="4">
<item row="5" column="3">
<widget class="QPushButton" name="send">
<property name="text">
<string>Send</string>
<string>&amp;Send</string>
</property>
</widget>
</item>
<item row="0" column="2" colspan="3">
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="total">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLineEdit" name="destination">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -400,7 +478,23 @@
</property>
</widget>
</item>
<item row="2" column="2" colspan="3">
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="calculatedName">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QComboBox" name="valueUnits"/>
</item>
<item row="3" column="1" colspan="3">
<widget class="QLabel" name="fee">
<property name="text">
<string/>
@ -410,11 +504,17 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="4">
<widget class="QLabel" name="total">
<property name="text">
<item row="2" column="1" colspan="2">
<widget class="QSpinBox" name="value">
<property name="suffix">
<string/>
</property>
<property name="maximum">
<number>430000000</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
</layout>
@ -432,11 +532,23 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_7">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="ourAccounts">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -451,6 +563,184 @@
</layout>
</widget>
</widget>
<widget class="QToolBar" name="toolBar_2">
<property name="windowTitle">
<string>toolBar_2</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QDockWidget" name="dockWidget_6">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Contracts</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QListWidget" name="contracts">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
<widget class="QPlainTextEdit" name="contractInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_8">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Block Chain</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_8">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QListWidget" name="blocks">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
<widget class="QPlainTextEdit" name="info">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_9">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_9">
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Name Registrar</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameReg"/>
</item>
</layout>
</widget>
</widget>
<action name="quit">
<property name="text">
<string>&amp;Quit</string>
@ -498,8 +788,34 @@
<string>&amp;About...</string>
</property>
</action>
<action name="preview">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preview</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>destination</tabstop>
<tabstop>calculatedName</tabstop>
<tabstop>value</tabstop>
<tabstop>valueUnits</tabstop>
<tabstop>data</tabstop>
<tabstop>code</tabstop>
<tabstop>send</tabstop>
<tabstop>idealPeers</tabstop>
<tabstop>port</tabstop>
<tabstop>clientName</tabstop>
<tabstop>verbosity</tabstop>
<tabstop>transactionQueue</tabstop>
<tabstop>accounts</tabstop>
<tabstop>peers</tabstop>
<tabstop>log</tabstop>
<tabstop>ourAccounts</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

477
alethzero/MainWin.cpp

@ -1,16 +1,54 @@
#include <QtNetwork/QNetworkReply>
#include <QtWidgets>
#include <QtCore>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <libethereum/Dagger.h>
#include <libethereum/Client.h>
#include <libethereum/Instruction.h>
#include "MainWin.h"
#include "ui_Main.h"
using namespace std;
using namespace eth;
// types
using eth::bytes;
using eth::bytesConstRef;
using eth::h160;
using eth::h256;
using eth::u160;
using eth::u256;
using eth::Address;
using eth::BlockInfo;
using eth::Client;
using eth::Instruction;
using eth::KeyPair;
using eth::NodeMode;
using eth::PeerInfo;
using eth::RLP;
using eth::Secret;
using eth::Transaction;
// functions
using eth::asHex;
using eth::assemble;
using eth::compileLisp;
using eth::disassemble;
using eth::formatBalance;
using eth::fromUserHex;
using eth::right160;
using eth::simpleDebugOut;
using eth::toLog2;
using eth::toString;
using eth::units;
// vars
using eth::g_logPost;
using eth::g_logVerbosity;
using eth::c_instructionInfo;
static void initUnits(QComboBox* _b)
{
for (int n = units().size() - 1; n >= 0; --n)
for (auto n = (::uint)units().size(); n-- != 0; )
_b->addItem(QString::fromStdString(units()[n].second), n);
_b->setCurrentIndex(6);
}
@ -25,14 +63,57 @@ Main::Main(QWidget *parent) :
setWindowFlags(Qt::Window);
ui->setupUi(this);
g_logPost = [=](std::string const& s, char const* c) { simpleDebugOut(s, c); ui->log->addItem(QString::fromStdString(s)); };
m_client = new Client("AlethZero");
m_client.reset(new Client("AlethZero"));
/*
ui->librariesView->setModel(m_libraryMan);
ui->graphsView->setModel(m_graphMan);
setWindowIcon(QIcon(":/Noted.png"));
qmlRegisterSingletonType<TimeHelper>("com.llr", 1, 0, "Time", TimelineItem::constructTimeHelper);
qmlRegisterType<GraphItem>("com.llr", 1, 0, "Graph");
qmlRegisterType<CursorGraphItem>("com.llr", 1, 0, "CursorGraph");
qmlRegisterType<IntervalItem>("com.llr", 1, 0, "Interval");
qmlRegisterType<CursorItem>("com.llr", 1, 0, "Cursor");
qmlRegisterType<TimelinesItem>("com.llr", 1, 0, "Timelines");
qmlRegisterType<TimeLabelsItem>("com.llr", 1, 0, "TimeLabels");
qmlRegisterType<XLabelsItem>("com.llr", 1, 0, "XLabels");
qmlRegisterType<XScaleItem>("com.llr", 1, 0, "XScale");
qmlRegisterType<YLabelsItem>("com.llr", 1, 0, "YLabels");
qmlRegisterType<YScaleItem>("com.llr", 1, 0, "YScale");
m_view = new QQuickView();
QQmlContext* context = m_view->rootContext();
context->setContextProperty("libs", libs());
context->setContextProperty("compute", compute());
context->setContextProperty("data", data());
context->setContextProperty("graphs", graphs());
context->setContextProperty("audio", audio());
context->setContextProperty("view", view());
m_view->setSource(QUrl("qrc:/Noted.qml"));
QWidget* w = QWidget::createWindowContainer(m_view);
w->setAcceptDrops(true);
m_view->setResizeMode(QQuickView::SizeRootObjectToView);
ui->fullDisplay->insertWidget(0, w);
m_view->create();
m_timelinesItem = m_view->rootObject()->findChild<TimelinesItem*>("timelines");
qDebug() << m_view->rootObject();
*/
readSettings();
refresh();
m_refresh = new QTimer(this);
connect(m_refresh, SIGNAL(timeout()), SLOT(refresh()));
m_refresh->start(1000);
m_refresh->start(100);
m_refreshNetwork = new QTimer(this);
connect(m_refreshNetwork, SIGNAL(timeout()), SLOT(refreshNetwork()));
m_refreshNetwork->start(1000);
connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved()));
#if ETH_DEBUG
m_servers.append("192.168.0.10:30301");
@ -41,30 +122,67 @@ Main::Main(QWidget *parent) :
{
m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts);
});
QNetworkRequest r(QUrl("http://www.ethereum.org/servers.poc2.txt"));
QNetworkRequest r(QUrl("http://www.ethereum.org/servers.poc3.txt"));
r.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1712.0 Safari/537.36");
m_webCtrl.get(r);
srand(time(0));
#endif
on_verbosity_sliderMoved();
initUnits(ui->valueUnits);
on_destination_textChanged();
statusBar()->addPermanentWidget(ui->balance);
statusBar()->addPermanentWidget(ui->peerCount);
statusBar()->addPermanentWidget(ui->blockChain);
statusBar()->addPermanentWidget(ui->blockCount);
}
Main::~Main()
{
g_logPost = simpleDebugOut;
writeSettings();
delete ui;
}
QString Main::pretty(eth::Address _a) const
{
if (h256 n = state().contractMemory(m_nameReg, (h256)(u256)(u160)_a))
{
std::string s((char const*)n.data(), 32);
if (s.find_first_of('\0') != string::npos)
s.resize(s.find_first_of('\0'));
return QString::fromStdString(s);
}
return QString();
}
QString Main::render(eth::Address _a) const
{
QString p = pretty(_a);
if (!p.isNull())
return p + " (" + QString::fromStdString(_a.abridged()) + ")";
return QString::fromStdString(_a.abridged());
}
Address Main::fromString(QString const& _a) const
{
string sn = _a.toStdString();
if (sn.size() > 32)
sn.resize(32);
h256 n;
memcpy(n.data(), sn.data(), sn.size());
memset(n.data() + sn.size(), 0, 32 - sn.size());
if (_a.size())
if (h256 a = state().contractMemory(m_nameReg, n))
return right160(a);
if (_a.size() == 40)
return Address(fromUserHex(_a.toStdString()));
else
return Address();
}
void Main::on_about_triggered()
{
QMessageBox::about(this, "About AlethZero PoC-2", "AlethZero/v" ADD_QUOTES(ETH_VERSION) "/" ADD_QUOTES(ETH_BUILD_TYPE) "/" ADD_QUOTES(ETH_BUILD_PLATFORM) "\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nTeam Ethereum++ includes: Eric Lombrozo, Marko Simovic, Alex Leverington and several others.");
QMessageBox::about(this, "About AlethZero PoC-3", "AlethZero/v" ADD_QUOTES(ETH_VERSION) "/" ADD_QUOTES(ETH_BUILD_TYPE) "/" ADD_QUOTES(ETH_BUILD_PLATFORM) "\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nTeam Ethereum++ includes: Eric Lombrozo, Marko Simovic, Alex Leverington, Tim Hughes and several others.");
}
void Main::writeSettings()
@ -88,12 +206,14 @@ void Main::writeSettings()
if (m_client->peerServer())
{
bytes d = m_client->peerServer()->savePeers();
m_peers = QByteArray((char*)d.data(), d.size());
m_peers = QByteArray((char*)d.data(), (int)d.size());
}
s.setValue("peers", m_peers);
s.setValue("nameReg", ui->nameReg->text());
s.setValue("geometry", saveGeometry());
s.setValue("windowState", saveState());
}
void Main::readSettings()
@ -101,6 +221,8 @@ void Main::readSettings()
QSettings s("ethereum", "alethzero");
restoreGeometry(s.value("geometry").toByteArray());
restoreState(s.value("windowState").toByteArray());
QByteArray b = s.value("address").toByteArray();
if (b.isEmpty())
@ -120,64 +242,255 @@ void Main::readSettings()
ui->clientName->setText(s.value("clientName", "").toString());
ui->idealPeers->setValue(s.value("idealPeers", ui->idealPeers->value()).toInt());
ui->port->setValue(s.value("port", ui->port->value()).toInt());
ui->nameReg->setText(s.value("nameReg", "11f62328e131dbb05ce4c73a3de3c7ab1c84a163").toString());
}
void Main::refresh()
void Main::on_nameReg_textChanged()
{
m_client->lock();
//if (m_client->changed())
string s = ui->nameReg->text().toStdString();
if (s.size() == 40)
{
ui->peerCount->setText(QString::fromStdString(toString(m_client->peerCount())) + " peer(s)");
ui->peers->clear();
for (PeerInfo const& i: m_client->peers())
ui->peers->addItem(QString("%3 ms - %1:%2 - %4").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count()).arg(i.clientVersion.c_str()));
m_nameReg = Address(fromUserHex(s));
refresh(true);
}
}
void Main::refreshNetwork()
{
auto ps = m_client->peers();
ui->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)");
ui->peers->clear();
for (PeerInfo const& i: ps)
ui->peers->addItem(QString("%3 ms - %1:%2 - %4").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count()).arg(i.clientVersion.c_str()));
}
eth::State const& Main::state() const
{
return ui->preview->isChecked() ? m_client->postState() : m_client->state();
}
void Main::refresh(bool _override)
{
m_client->lock();
auto const& st = state();
bool c = m_client->changed();
if (c || _override)
{
auto d = m_client->blockChain().details();
auto diff = BlockInfo(m_client->blockChain().block()).difficulty;
ui->blockChain->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)));
ui->blockCount->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)));
auto acs = m_client->state().addresses();
auto acs = st.addresses();
ui->accounts->clear();
for (auto i: acs)
ui->accounts->addItem(QString("%1 @ %2").arg(formatBalance(i.second).c_str()).arg(asHex(i.first.asArray()).c_str()));
ui->contracts->clear();
for (auto n = 0; n < 2; ++n)
for (auto i: acs)
{
auto r = render(i.first);
if (r.contains('(') == !n)
{
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(i.second).c_str()).arg(r).arg((unsigned)state().transactionsFrom(i.first)), ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size));
if (st.isContractAddress(i.first))
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(i.second).c_str()).arg(r).arg((unsigned)st.transactionsFrom(i.first)), ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size));
}
}
ui->transactionQueue->clear();
for (pair<h256, Transaction> const& i: m_client->pending())
for (Transaction const& t: m_client->pending())
{
ui->transactionQueue->addItem(QString("%1 [%4] @ %2 <- %3")
.arg(formatBalance(i.second.value).c_str())
.arg(asHex(i.second.receiveAddress.asArray()).c_str())
.arg(asHex(i.second.sender().asArray()).c_str())
.arg((unsigned)i.second.nonce));
QString s = t.receiveAddress ?
QString("%2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value).c_str())
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress))
.arg((unsigned)t.nonce)
.arg(st.isContractAddress(t.receiveAddress) ? '*' : '-') :
QString("%2 +> %3: %1 [%4]")
.arg(formatBalance(t.value).c_str())
.arg(render(t.safeSender()))
.arg(render(right160(t.sha3())))
.arg((unsigned)t.nonce);
ui->transactionQueue->addItem(s);
}
ui->transactions->clear();
ui->blocks->clear();
auto const& bc = m_client->blockChain();
for (auto h = bc.currentHash(); h != bc.genesisHash(); h = bc.details(h).parent)
{
auto d = bc.details(h);
ui->transactions->addItem(QString("# %1 ==== %2").arg(d.number).arg(asHex(h.asArray()).c_str()));
QListWidgetItem* blockItem = new QListWidgetItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), ui->blocks);
blockItem->setData(Qt::UserRole, QByteArray((char const*)h.data(), h.size));
int n = 0;
for (auto const& i: RLP(bc.block(h))[1])
{
Transaction t(i.data());
ui->transactions->addItem(QString("%1 [%4] @ %2 <- %3")
.arg(formatBalance(t.value).c_str())
.arg(asHex(t.receiveAddress.asArray()).c_str())
.arg(asHex(t.sender().asArray()).c_str())
.arg((unsigned)t.nonce));
QString s = t.receiveAddress ?
QString(" %2 %5> %3: %1 [%4]")
.arg(formatBalance(t.value).c_str())
.arg(render(t.safeSender()))
.arg(render(t.receiveAddress))
.arg((unsigned)t.nonce)
.arg(st.isContractAddress(t.receiveAddress) ? '*' : '-') :
QString(" %2 +> %3: %1 [%4]")
.arg(formatBalance(t.value).c_str())
.arg(render(t.safeSender()))
.arg(render(right160(t.sha3())))
.arg((unsigned)t.nonce);
QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks);
txItem->setData(Qt::UserRole, QByteArray((char const*)h.data(), h.size));
txItem->setData(Qt::UserRole + 1, n);
n++;
}
}
}
ui->ourAccounts->clear();
u256 totalBalance = 0;
for (auto i: m_myKeys)
if (c || m_keysChanged || _override)
{
m_keysChanged = false;
ui->ourAccounts->clear();
u256 totalBalance = 0;
for (auto i: m_myKeys)
{
u256 b = st.balance(i.address());
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(b).c_str()).arg(render(i.address())).arg((unsigned)st.transactionsFrom(i.address())), ui->ourAccounts))
->setData(Qt::UserRole, QByteArray((char const*)i.address().data(), Address::size));
totalBalance += b;
}
ui->balance->setText(QString::fromStdString(formatBalance(totalBalance)));
}
m_client->unlock();
}
void Main::ourAccountsRowsMoved()
{
QVector<KeyPair> myKeys;
for (int i = 0; i < ui->ourAccounts->count(); ++i)
{
auto hba = ui->ourAccounts->item(i)->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
for (auto i: m_myKeys)
if (i.address() == h)
myKeys.push_back(i);
}
m_myKeys = myKeys;
}
void Main::on_blocks_currentItemChanged()
{
ui->info->clear();
m_client->lock();
if (auto item = ui->blocks->currentItem())
{
u256 b = m_client->state().balance(i.address());
ui->ourAccounts->addItem(QString("%1 @ %2").arg(formatBalance(b).c_str()).arg(asHex(i.address().asArray()).c_str()));
totalBalance += b;
auto hba = item->data(Qt::UserRole).toByteArray();
assert(hba.size() == 32);
auto h = h256((byte const*)hba.data(), h256::ConstructFromPointer);
auto details = m_client->blockChain().details(h);
auto blockData = m_client->blockChain().block(h);
auto block = RLP(blockData);
BlockInfo info(blockData);
stringstream s;
if (item->data(Qt::UserRole + 1).isNull())
{
char timestamp[64];
time_t rawTime = (time_t)(uint64_t)info.timestamp;
strftime(timestamp, 64, "%c", localtime(&rawTime));
s << "<h3>" << h << "</h3>";
s << "<h4>#" << details.number;
s << "&nbsp;&emsp;&nbsp;<b>" << timestamp << "</b></h4>";
s << "<br/>D/TD: <b>2^" << log2((double)info.difficulty) << "</b>/<b>2^" << log2((double)details.totalDifficulty) << "</b>";
s << "&nbsp;&emsp;&nbsp;Children: <b>" << details.children.size() << "</b></h5>";
s << "<br/>Coinbase: <b>" << pretty(info.coinbaseAddress).toStdString() << "</b> " << info.coinbaseAddress;
s << "<br/>State: <b>" << info.stateRoot << "</b>";
s << "<br/>Nonce: <b>" << info.nonce << "</b>";
s << "<br/>Transactions: <b>" << block[1].itemCount() << "</b> @<b>" << info.sha3Transactions << "</b>";
s << "<br/>Uncles: <b>" << block[2].itemCount() << "</b> @<b>" << info.sha3Uncles << "</b>";
}
else
{
unsigned txi = item->data(Qt::UserRole + 1).toInt();
Transaction tx(block[1][txi].data());
h256 th = tx.sha3();
s << "<h3>" << th << "</h3>";
s << "<h4>" << h << "[<b>" << txi << "</b>]</h4>";
auto ss = tx.safeSender();
s << "<br/>From: <b>" << pretty(ss).toStdString() << "</b> " << ss;
if (tx.receiveAddress)
s << "<br/>To: <b>" << pretty(tx.receiveAddress).toStdString() << "</b> " << tx.receiveAddress;
else
s << "<br/>Creates: <b>" << pretty(right160(th)).toStdString() << "</b> " << right160(th);
s << "<br/>Value: <b>" << formatBalance(tx.value) << "</b>";
s << "&nbsp;&emsp;&nbsp;#<b>" << tx.nonce << "</b>";
if (tx.data.size())
{
s << "<br/>Data:&nbsp;&emsp;&nbsp;";
// for (auto i: tx.data)
// s << "0x<b>" << hex << i << "</b>&emsp;";
s << "</br>" << disassemble(tx.data);
}
}
ui->info->appendHtml(QString::fromStdString(s.str()));
}
m_client->unlock();
}
void Main::on_contracts_currentItemChanged()
{
ui->contractInfo->clear();
m_client->lock();
if (auto item = ui->contracts->currentItem())
{
auto hba = item->data(Qt::UserRole).toByteArray();
assert(hba.size() == 20);
auto h = h160((byte const*)hba.data(), h160::ConstructFromPointer);
stringstream s;
auto mem = state().contractMemory(h);
u256 next = 0;
unsigned numerics = 0;
bool unexpectedNumeric = false;
for (auto i: mem)
{
if (next < i.first)
{
unsigned j;
for (j = 0; j <= numerics && next + j < i.first; ++j)
s << (j < numerics || unexpectedNumeric ? " 0" : " <b>STOP</b>");
unexpectedNumeric = false;
numerics -= min(numerics, j);
if (next + j < i.first)
s << " ...<br/>@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;";
}
else if (!next)
{
s << "@" << showbase << hex << i.first << "&nbsp;&nbsp;&nbsp;&nbsp;";
}
auto iit = c_instructionInfo.find((Instruction)(unsigned)i.second);
if (numerics || iit == c_instructionInfo.end() || (u256)(unsigned)iit->first != i.second) // not an instruction or expecting an argument...
{
if (numerics)
numerics--;
else
unexpectedNumeric = true;
s << " " << showbase << hex << i.second;
}
else
{
auto const& ii = iit->second;
s << " <b>" << ii.name << "</b>";
numerics = ii.additional;
}
next = i.first + 1;
}
ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
}
ui->balance->setText(QString::fromStdString(formatBalance(totalBalance)));
m_client->unlock();
}
@ -189,7 +502,9 @@ void Main::on_idealPeers_valueChanged()
void Main::on_ourAccounts_doubleClicked()
{
qApp->clipboard()->setText(ui->ourAccounts->currentItem()->text().section(" @ ", 1));
auto hba = ui->ourAccounts->currentItem()->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
qApp->clipboard()->setText(QString::fromStdString(asHex(h.asArray())));
}
void Main::on_log_doubleClicked()
@ -199,23 +514,41 @@ void Main::on_log_doubleClicked()
void Main::on_accounts_doubleClicked()
{
qApp->clipboard()->setText(ui->accounts->currentItem()->text().section(" @ ", 1));
auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
qApp->clipboard()->setText(QString::fromStdString(asHex(h.asArray())));
}
void Main::on_contracts_doubleClicked()
{
auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray();
auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer);
qApp->clipboard()->setText(QString::fromStdString(asHex(h.asArray())));
}
void Main::on_destination_textChanged()
{
if (ui->destination->text().size())
if (Address a = fromString(ui->destination->text()))
ui->calculatedName->setText(render(a));
else
ui->calculatedName->setText("Unknown Address");
else
ui->calculatedName->setText("Create Contract");
updateFee();
}
void Main::on_data_textChanged()
{
m_data = ui->data->toPlainText().split(QRegExp("[^0-9a-fA-Fx]+"), QString::SkipEmptyParts);
string code = ui->data->toPlainText().toStdString();
m_data = code[0] == '(' ? compileLisp(code, true) : assemble(code, true);
ui->code->setPlainText(QString::fromStdString(disassemble(m_data)));
updateFee();
}
u256 Main::fee() const
{
return (ui->destination->text().isEmpty() || !ui->destination->text().toInt()) ? m_client->state().fee(m_data.size()) : m_client->state().fee();
return (ui->destination->text().isEmpty() || !ui->destination->text().toInt()) ? state().fee(m_data.size()) : state().fee();
}
u256 Main::value() const
@ -236,7 +569,7 @@ void Main::updateFee()
bool ok = false;
for (auto i: m_myKeys)
if (m_client->state().balance(i.address()) >= totalReq)
if (state().balance(i.address()) >= totalReq)
{
ok = true;
break;
@ -278,7 +611,7 @@ void Main::on_connect_triggered()
if (ok && s.contains(":"))
{
string host = s.section(":", 0, 0).toStdString();
short port = s.section(":", 1).toInt();
unsigned short port = s.section(":", 1).toInt();
m_client->connect(host, port);
}
}
@ -304,24 +637,12 @@ void Main::on_send_clicked()
u256 totalReq = value() + fee();
m_client->lock();
for (auto i: m_myKeys)
if (m_client->state().balance(i.address()) >= totalReq && i.address() != Address(fromUserHex(ui->destination->text().toStdString())))
if (m_client->state().balance(i.address()) >= totalReq )
{
m_client->unlock();
Secret s = i.secret();
Address r = Address(fromUserHex(ui->destination->text().toStdString()));
u256s data;
data.reserve(m_data.size());
for (QString const& i: m_data)
{
u256 d = 0;
try
{
d = u256(i.toStdString());
}
catch (...) {}
data.push_back(d);
}
m_client->transact(s, r, value(), data);
Address r = fromString(ui->destination->text());
m_client->transact(s, r, value(), m_data);
refresh();
return;
}
@ -332,4 +653,32 @@ void Main::on_send_clicked()
void Main::on_create_triggered()
{
m_myKeys.append(KeyPair::create());
m_keysChanged = true;
}
// extra bits needed to link on VS
#ifdef _MSC_VER
// include moc file, ofuscated to hide from automoc
#include\
"moc_MainWin.cpp"
// specify library dependencies, it's easier to do here than in the project since we can control the "d" debug suffix
#ifdef _DEBUG
#define QTLIB(x) x"d.lib"
#else
#define QTLIB(x) x".lib"
#endif
#pragma comment(lib, QTLIB("Qt5PlatformSupport"))
#pragma comment(lib, QTLIB("Qt5Core"))
#pragma comment(lib, QTLIB("Qt5GUI"))
#pragma comment(lib, QTLIB("Qt5Widgets"))
#pragma comment(lib, QTLIB("Qt5Network"))
#pragma comment(lib, QTLIB("qwindows"))
#pragma comment(lib, "Imm32.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "winmm.lib")
#endif

32
alethzero/MainWin.h

@ -2,9 +2,9 @@
#define MAIN_H
#include <QtNetwork/QNetworkAccessManager>
#include <QAbstractListModel>
#include <QMainWindow>
#include <QMutex>
#include <QtCore/QAbstractListModel>
#include <QtCore/QMutex>
#include <QtWidgets/QMainWindow>
#include <libethereum/Common.h>
namespace Ui {
@ -13,6 +13,7 @@ class Main;
namespace eth {
class Client;
class State;
}
class Main : public QMainWindow
@ -31,6 +32,7 @@ private slots:
void on_net_triggered();
void on_verbosity_sliderMoved();
void on_ourAccounts_doubleClicked();
void ourAccountsRowsMoved();
void on_accounts_doubleClicked();
void on_destination_textChanged();
void on_data_textChanged();
@ -38,12 +40,25 @@ private slots:
void on_value_valueChanged() { updateFee(); }
void on_valueUnits_currentIndexChanged() { updateFee(); }
void on_log_doubleClicked();
void on_blocks_currentItemChanged();
void on_contracts_doubleClicked();
void on_contracts_currentItemChanged();
void on_about_triggered();
void on_nameReg_textChanged();
void on_preview_triggered() { refresh(true); }
void on_quit_triggered() { close(); }
void refresh();
void refresh(bool _override = false);
void refreshNetwork();
private:
QString pretty(eth::Address _a) const;
QString render(eth::Address _a) const;
eth::Address fromString(QString const& _a) const;
eth::State const& state() const;
void updateFee();
void readSettings();
void writeSettings();
@ -52,16 +67,19 @@ private:
eth::u256 total() const;
eth::u256 value() const;
Ui::Main *ui;
std::unique_ptr<Ui::Main> ui;
eth::Client* m_client;
std::unique_ptr<eth::Client> m_client;
QByteArray m_peers;
QMutex m_guiLock;
QTimer* m_refresh;
QTimer* m_refreshNetwork;
QStringList m_servers;
QVector<eth::KeyPair> m_myKeys;
QStringList m_data;
bool m_keysChanged = false;
eth::u256s m_data;
eth::Address m_nameReg;
QNetworkAccessManager m_webCtrl;
};

2
alethzero/main.cpp

@ -1,5 +1,5 @@
#include "MainWin.h"
#include <QApplication>
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{

128
eth/main.cpp

@ -35,26 +35,6 @@ using namespace eth;
#define ADD_QUOTES_HELPER(s) #s
#define ADD_QUOTES(s) ADD_QUOTES_HELPER(s)
bytes contents(std::string const& _file)
{
std::ifstream is(_file, std::ifstream::binary);
if (!is)
return bytes();
// get length of file:
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);
bytes ret(length);
is.read((char*)ret.data(), length);
is.close();
return ret;
}
void writeFile(std::string const& _file, bytes const& _data)
{
ofstream(_file, ios::trunc).write((char const*)_data.data(), _data.size());
}
bool isTrue(std::string const& _m)
{
return _m == "on" || _m == "yes" || _m == "true" || _m == "1";
@ -68,82 +48,26 @@ bool isFalse(std::string const& _m)
void help()
{
cout
<< "Usage eth [OPTIONS] <remote-host>" << endl
<< "Options:" << endl
<< " -l,--listen <port> Listen on the given port for incoming connected (default: 30303)." << endl
<< " -l,--listen <port> Listen on the given port for incoming connected (default: 30303)." << endl
<< " -l,--listen <port> Listen on the given port for incoming connected (default: 30303)." << endl
;
/*
if ((arg == "-l" || arg == "--listen" || arg == "--listen-port") && i + 1 < argc)
listenPort = atoi(argv[++i]);
else if ((arg == "-u" || arg == "--public-ip" || arg == "--public") && i + 1 < argc)
publicIP = argv[++i];
else if ((arg == "-r" || arg == "--remote") && i + 1 < argc)
remoteHost = argv[++i];
else if ((arg == "-p" || arg == "--port") && i + 1 < argc)
remotePort = atoi(argv[++i]);
else if ((arg == "-n" || arg == "--upnp") && i + 1 < argc)
{
string m = argv[++i];
if (isTrue(m))
upnp = true;
else if (isFalse(m))
upnp = false;
else
{
cerr << "Invalid UPnP option: " << m << endl;
return -1;
}
}
else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc)
clientName = argv[++i];
else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc)
coinbase = h160(fromUserHex(argv[++i]));
else if ((arg == "-s" || arg == "--secret") && i + 1 < argc)
us = KeyPair(h256(fromUserHex(argv[++i])));
else if (arg == "-i" || arg == "--interactive")
interactive = true;
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc)
dbPath = argv[++i];
else if ((arg == "-m" || arg == "--mining") && i + 1 < argc)
{
string m = argv[++i];
if (isTrue(m))
mining = ~(eth::uint)0;
else if (isFalse(m))
mining = 0;
else if (int i = stoi(m))
mining = i;
else
{
cerr << "Unknown mining option: " << m << endl;
return -1;
}
}
else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc)
g_logVerbosity = atoi(argv[++i]);
else if ((arg == "-x" || arg == "--peers") && i + 1 < argc)
peers = atoi(argv[++i]);
else if ((arg == "-o" || arg == "--mode") && i + 1 < argc)
{
string m = argv[++i];
if (m == "full")
mode = NodeMode::Full;
else if (m == "peer")
mode = NodeMode::PeerServer;
else
{
cerr << "Unknown mode: " << m << endl;
return -1;
}
}
else if (arg == "-h" || arg == "--help")
help();
else if (arg == "-V" || arg == "--version")
version();
*/
exit(0);
<< "Usage eth [OPTIONS] <remote-host>" << endl
<< "Options:" << endl
<< " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl
<< " -c,--client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " -d,--db-path <path> Load database from path (default: ~/.ethereum " << endl
<< " <APPDATA>/Etherum or Library/Application Support/Ethereum)." << endl
<< " -h,--help Show this help message and exit." << endl
<< " -i,--interactive Enter interactive mode (default: non-interactive)." << endl
<< " -l,--listen <port> Listen on the given port for incoming connected (default: 30303)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (Default: off)" << endl
<< " -n,--upnp <on/off> Use upnp for NAT (default: on)." << endl
<< " -o,--mode <full/peer> Start a full node or a peer node (Default: full)." << endl
<< " -p,--port <port> Connect to remote port (default: 30303)." << endl
<< " -r,--remote <host> Connect to remote host (default: none)." << endl
<< " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl
<< " -u,--public-ip <ip> Force public ip to given (default; auto)." << endl
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (Default: 8)." << endl
<< " -x,--peers <number> Attempt to connect to given number of peers (Default: 5)." << endl
<< " -V,--version Show the version and exit." << endl;
exit(0);
}
void version()
@ -155,9 +79,9 @@ void version()
int main(int argc, char** argv)
{
short listenPort = 30303;
unsigned short listenPort = 30303;
string remoteHost;
short remotePort = 30303;
unsigned short remotePort = 30303;
bool interactive = false;
string dbPath;
eth::uint mining = ~(eth::uint)0;
@ -193,13 +117,13 @@ int main(int argc, char** argv)
{
string arg = argv[i];
if ((arg == "-l" || arg == "--listen" || arg == "--listen-port") && i + 1 < argc)
listenPort = atoi(argv[++i]);
listenPort = (short)atoi(argv[++i]);
else if ((arg == "-u" || arg == "--public-ip" || arg == "--public") && i + 1 < argc)
publicIP = argv[++i];
else if ((arg == "-r" || arg == "--remote") && i + 1 < argc)
remoteHost = argv[++i];
else if ((arg == "-p" || arg == "--port") && i + 1 < argc)
remotePort = atoi(argv[++i]);
remotePort = (short)atoi(argv[++i]);
else if ((arg == "-n" || arg == "--upnp") && i + 1 < argc)
{
string m = argv[++i];
@ -282,14 +206,14 @@ int main(int argc, char** argv)
{
eth::uint port;
cin >> port;
c.startNetwork(port);
c.startNetwork((short)port);
}
else if (cmd == "connect")
{
string addr;
eth::uint port;
cin >> addr >> port;
c.connect(addr, port);
c.connect(addr, (short)port);
}
else if (cmd == "netstop")
{

10
json_spirit/CMakeLists.txt

@ -0,0 +1,10 @@
SET(JSON_SPIRIT_SRCS
json_spirit_reader.cpp
json_spirit_value.cpp
json_spirit_writer.cpp)
FIND_PACKAGE(Boost 1.34 REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_LIBRARY(json_spirit STATIC ${JSON_SPIRIT_SRCS})

18
json_spirit/json_spirit.h

@ -0,0 +1,18 @@
#ifndef JSON_SPIRIT
#define JSON_SPIRIT
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include "json_spirit_value.h"
#include "json_spirit_reader.h"
#include "json_spirit_writer.h"
#include "json_spirit_utils.h"
#endif

209
json_spirit/json_spirit.vcproj

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="json_spirit_lib"
ProjectGUID="{BE262A86-CC26-4B25-A877-883ED2688CEC}"
RootNamespace="json_spirit"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&#x0D;&#x0A;"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="false"
FavorSizeOrSpeed="0"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\json_spirit_reader.cpp"
>
</File>
<File
RelativePath=".\json_spirit_writer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\json_spirit.h"
>
</File>
<File
RelativePath=".\json_spirit_error_position.h"
>
</File>
<File
RelativePath=".\json_spirit_reader.h"
>
</File>
<File
RelativePath=".\json_spirit_reader_template.h"
>
</File>
<File
RelativePath=".\json_spirit_stream_reader.h"
>
</File>
<File
RelativePath=".\json_spirit_utils.h"
>
</File>
<File
RelativePath=".\json_spirit_value.h"
>
</File>
<File
RelativePath=".\json_spirit_writer.h"
>
</File>
<File
RelativePath=".\json_spirit_writer_template.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

54
json_spirit/json_spirit_error_position.h

@ -0,0 +1,54 @@
#ifndef JSON_SPIRIT_ERROR_POSITION
#define JSON_SPIRIT_ERROR_POSITION
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <string>
namespace json_spirit
{
// An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
// Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
// functions that return a bool.
//
struct Error_position
{
Error_position();
Error_position( unsigned int line, unsigned int column, const std::string& reason );
bool operator==( const Error_position& lhs ) const;
unsigned int line_;
unsigned int column_;
std::string reason_;
};
inline Error_position::Error_position()
: line_( 0 )
, column_( 0 )
{
}
inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
: line_( line )
, column_( column )
, reason_( reason )
{
}
inline bool Error_position::operator==( const Error_position& lhs ) const
{
if( this == &lhs ) return true;
return ( reason_ == lhs.reason_ ) &&
( line_ == lhs.line_ ) &&
( column_ == lhs.column_ );
}
}
#endif

137
json_spirit/json_spirit_reader.cpp

@ -0,0 +1,137 @@
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#include "json_spirit_reader.h"
#include "json_spirit_reader_template.h"
using namespace json_spirit;
bool json_spirit::read( const std::string& s, Value& value )
{
return read_string( s, value );
}
void json_spirit::read_or_throw( const std::string& s, Value& value )
{
read_string_or_throw( s, value );
}
bool json_spirit::read( std::istream& is, Value& value )
{
return read_stream( is, value );
}
void json_spirit::read_or_throw( std::istream& is, Value& value )
{
read_stream_or_throw( is, value );
}
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
{
return read_range( begin, end, value );
}
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
{
begin = read_range_or_throw( begin, end, value );
}
#ifndef BOOST_NO_STD_WSTRING
bool json_spirit::read( const std::wstring& s, wValue& value )
{
return read_string( s, value );
}
void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
{
read_string_or_throw( s, value );
}
bool json_spirit::read( std::wistream& is, wValue& value )
{
return read_stream( is, value );
}
void json_spirit::read_or_throw( std::wistream& is, wValue& value )
{
read_stream_or_throw( is, value );
}
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
{
return read_range( begin, end, value );
}
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
{
begin = read_range_or_throw( begin, end, value );
}
#endif
bool json_spirit::read( const std::string& s, mValue& value )
{
return read_string( s, value );
}
void json_spirit::read_or_throw( const std::string& s, mValue& value )
{
read_string_or_throw( s, value );
}
bool json_spirit::read( std::istream& is, mValue& value )
{
return read_stream( is, value );
}
void json_spirit::read_or_throw( std::istream& is, mValue& value )
{
read_stream_or_throw( is, value );
}
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
{
return read_range( begin, end, value );
}
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
{
begin = read_range_or_throw( begin, end, value );
}
#ifndef BOOST_NO_STD_WSTRING
bool json_spirit::read( const std::wstring& s, wmValue& value )
{
return read_string( s, value );
}
void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
{
read_string_or_throw( s, value );
}
bool json_spirit::read( std::wistream& is, wmValue& value )
{
return read_stream( is, value );
}
void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
{
read_stream_or_throw( is, value );
}
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
{
return read_range( begin, end, value );
}
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
{
begin = read_range_or_throw( begin, end, value );
}
#endif

62
json_spirit/json_spirit_reader.h

@ -0,0 +1,62 @@
#ifndef JSON_SPIRIT_READER
#define JSON_SPIRIT_READER
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include "json_spirit_value.h"
#include "json_spirit_error_position.h"
#include <iostream>
namespace json_spirit
{
// functions to reads a JSON values
bool read( const std::string& s, Value& value );
bool read( std::istream& is, Value& value );
bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
void read_or_throw( const std::string& s, Value& value );
void read_or_throw( std::istream& is, Value& value );
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
#ifndef BOOST_NO_STD_WSTRING
bool read( const std::wstring& s, wValue& value );
bool read( std::wistream& is, wValue& value );
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
void read_or_throw( const std::wstring& s, wValue& value );
void read_or_throw( std::wistream& is, wValue& value );
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
#endif
bool read( const std::string& s, mValue& value );
bool read( std::istream& is, mValue& value );
bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
void read_or_throw( const std::string& s, mValue& value );
void read_or_throw( std::istream& is, mValue& value );
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
#ifndef BOOST_NO_STD_WSTRING
bool read( const std::wstring& s, wmValue& value );
bool read( std::wistream& is, wmValue& value );
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
void read_or_throw( const std::wstring& s, wmValue& value );
void read_or_throw( std::wistream& is, wmValue& value );
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
#endif
}
#endif

612
json_spirit/json_spirit_reader_template.h

@ -0,0 +1,612 @@
#ifndef JSON_SPIRIT_READER_TEMPLATE
#define JSON_SPIRIT_READER_TEMPLATE
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#include "json_spirit_value.h"
#include "json_spirit_error_position.h"
//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION >= 103800
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_escape_char.hpp>
#include <boost/spirit/include/classic_multi_pass.hpp>
#include <boost/spirit/include/classic_position_iterator.hpp>
#define spirit_namespace boost::spirit::classic
#else
#include <boost/spirit/core.hpp>
#include <boost/spirit/utility/confix.hpp>
#include <boost/spirit/utility/escape_char.hpp>
#include <boost/spirit/iterator/multi_pass.hpp>
#include <boost/spirit/iterator/position_iterator.hpp>
#define spirit_namespace boost::spirit
#endif
namespace json_spirit
{
const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >();
const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
template< class Iter_type >
bool is_eq( Iter_type first, Iter_type last, const char* c_str )
{
for( Iter_type i = first; i != last; ++i, ++c_str )
{
if( *c_str == 0 ) return false;
if( *i != *c_str ) return false;
}
return true;
}
template< class Char_type >
Char_type hex_to_num( const Char_type c )
{
if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
return 0;
}
template< class Char_type, class Iter_type >
Char_type hex_str_to_char( Iter_type& begin )
{
const Char_type c1( *( ++begin ) );
const Char_type c2( *( ++begin ) );
return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
}
template< class Char_type, class Iter_type >
Char_type unicode_str_to_char( Iter_type& begin )
{
const Char_type c1( *( ++begin ) );
const Char_type c2( *( ++begin ) );
const Char_type c3( *( ++begin ) );
const Char_type c4( *( ++begin ) );
return ( hex_to_num( c1 ) << 12 ) +
( hex_to_num( c2 ) << 8 ) +
( hex_to_num( c3 ) << 4 ) +
hex_to_num( c4 );
}
template< class String_type >
void append_esc_char_and_incr_iter( String_type& s,
typename String_type::const_iterator& begin,
typename String_type::const_iterator end )
{
typedef typename String_type::value_type Char_type;
const Char_type c2( *begin );
switch( c2 )
{
case 't': s += '\t'; break;
case 'b': s += '\b'; break;
case 'f': s += '\f'; break;
case 'n': s += '\n'; break;
case 'r': s += '\r'; break;
case '\\': s += '\\'; break;
case '/': s += '/'; break;
case '"': s += '"'; break;
case 'x':
{
if( end - begin >= 3 ) // expecting "xHH..."
{
s += hex_str_to_char< Char_type >( begin );
}
break;
}
case 'u':
{
if( end - begin >= 5 ) // expecting "uHHHH..."
{
s += unicode_str_to_char< Char_type >( begin );
}
break;
}
}
}
template< class String_type >
String_type substitute_esc_chars( typename String_type::const_iterator begin,
typename String_type::const_iterator end )
{
typedef typename String_type::const_iterator Iter_type;
if( end - begin < 2 ) return String_type( begin, end );
String_type result;
result.reserve( end - begin );
const Iter_type end_minus_1( end - 1 );
Iter_type substr_start = begin;
Iter_type i = begin;
for( ; i < end_minus_1; ++i )
{
if( *i == '\\' )
{
result.append( substr_start, i );
++i; // skip the '\'
append_esc_char_and_incr_iter( result, i, end );
substr_start = i + 1;
}
}
result.append( substr_start, end );
return result;
}
template< class String_type >
String_type get_str_( typename String_type::const_iterator begin,
typename String_type::const_iterator end )
{
assert( end - begin >= 2 );
typedef typename String_type::const_iterator Iter_type;
Iter_type str_without_quotes( ++begin );
Iter_type end_without_quotes( --end );
return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
}
inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
{
return get_str_< std::string >( begin, end );
}
inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
{
return get_str_< std::wstring >( begin, end );
}
template< class String_type, class Iter_type >
String_type get_str( Iter_type begin, Iter_type end )
{
const String_type tmp( begin, end ); // convert multipass iterators to string iterators
return get_str( tmp.begin(), tmp.end() );
}
// this class's methods get called by the spirit parse resulting
// in the creation of a JSON object or array
//
// NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
//
template< class Value_type, class Iter_type >
class Semantic_actions
{
public:
typedef typename Value_type::Config_type Config_type;
typedef typename Config_type::String_type String_type;
typedef typename Config_type::Object_type Object_type;
typedef typename Config_type::Array_type Array_type;
typedef typename String_type::value_type Char_type;
Semantic_actions( Value_type& value )
: value_( value )
, current_p_( 0 )
{
}
void begin_obj( Char_type c )
{
assert( c == '{' );
begin_compound< Object_type >();
}
void end_obj( Char_type c )
{
assert( c == '}' );
end_compound();
}
void begin_array( Char_type c )
{
assert( c == '[' );
begin_compound< Array_type >();
}
void end_array( Char_type c )
{
assert( c == ']' );
end_compound();
}
void new_name( Iter_type begin, Iter_type end )
{
assert( current_p_->type() == obj_type );
name_ = get_str< String_type >( begin, end );
}
void new_str( Iter_type begin, Iter_type end )
{
add_to_current( get_str< String_type >( begin, end ) );
}
void new_true( Iter_type begin, Iter_type end )
{
assert( is_eq( begin, end, "true" ) );
add_to_current( true );
}
void new_false( Iter_type begin, Iter_type end )
{
assert( is_eq( begin, end, "false" ) );
add_to_current( false );
}
void new_null( Iter_type begin, Iter_type end )
{
assert( is_eq( begin, end, "null" ) );
add_to_current( Value_type() );
}
void new_int( boost::int64_t i )
{
add_to_current( i );
}
void new_uint64( boost::uint64_t ui )
{
add_to_current( ui );
}
void new_real( double d )
{
add_to_current( d );
}
private:
Semantic_actions& operator=( const Semantic_actions& );
// to prevent "assignment operator could not be generated" warning
Value_type* add_first( const Value_type& value )
{
assert( current_p_ == 0 );
value_ = value;
current_p_ = &value_;
return current_p_;
}
template< class Array_or_obj >
void begin_compound()
{
if( current_p_ == 0 )
{
add_first( Array_or_obj() );
}
else
{
stack_.push_back( current_p_ );
Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
current_p_ = add_to_current( new_array_or_obj );
}
}
void end_compound()
{
if( current_p_ != &value_ )
{
current_p_ = stack_.back();
stack_.pop_back();
}
}
Value_type* add_to_current( const Value_type& value )
{
if( current_p_ == 0 )
{
return add_first( value );
}
else if( current_p_->type() == array_type )
{
current_p_->get_array().push_back( value );
return &current_p_->get_array().back();
}
assert( current_p_->type() == obj_type );
return &Config_type::add( current_p_->get_obj(), name_, value );
}
Value_type& value_; // this is the object or array that is being created
Value_type* current_p_; // the child object or array that is currently being constructed
std::vector< Value_type* > stack_; // previous child objects and arrays
String_type name_; // of current name/value pair
};
template< typename Iter_type >
void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
{
throw Error_position( i.get_position().line, i.get_position().column, reason );
}
template< typename Iter_type >
void throw_error( Iter_type i, const std::string& reason )
{
throw reason;
}
// the spirit grammer
//
template< class Value_type, class Iter_type >
class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
{
public:
typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
Json_grammer( Semantic_actions_t& semantic_actions )
: actions_( semantic_actions )
{
}
static void throw_not_value( Iter_type begin, Iter_type end )
{
throw_error( begin, "not a value" );
}
static void throw_not_array( Iter_type begin, Iter_type end )
{
throw_error( begin, "not an array" );
}
static void throw_not_object( Iter_type begin, Iter_type end )
{
throw_error( begin, "not an object" );
}
static void throw_not_pair( Iter_type begin, Iter_type end )
{
throw_error( begin, "not a pair" );
}
static void throw_not_colon( Iter_type begin, Iter_type end )
{
throw_error( begin, "no colon in pair" );
}
static void throw_not_string( Iter_type begin, Iter_type end )
{
throw_error( begin, "not a string" );
}
template< typename ScannerT >
class definition
{
public:
definition( const Json_grammer& self )
{
using namespace spirit_namespace;
typedef typename Value_type::String_type::value_type Char_type;
// first we convert the semantic action class methods to functors with the
// parameter signature expected by spirit
typedef boost::function< void( Char_type ) > Char_action;
typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
typedef boost::function< void( double ) > Real_action;
typedef boost::function< void( boost::int64_t ) > Int_action;
typedef boost::function< void( boost::uint64_t ) > Uint64_action;
Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );
Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) );
Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) );
Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) );
Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) );
Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
// actual grammer
json_
= value_ | eps_p[ &throw_not_value ]
;
value_
= string_[ new_str ]
| number_
| object_
| array_
| str_p( "true" ) [ new_true ]
| str_p( "false" )[ new_false ]
| str_p( "null" ) [ new_null ]
;
object_
= ch_p('{')[ begin_obj ]
>> !members_
>> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
;
members_
= pair_ >> *( ',' >> pair_ )
;
pair_
= string_[ new_name ]
>> ( ':' | eps_p[ &throw_not_colon ] )
>> ( value_ | eps_p[ &throw_not_value ] )
;
array_
= ch_p('[')[ begin_array ]
>> !elements_
>> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
;
elements_
= value_ >> *( ',' >> value_ )
;
string_
= lexeme_d // this causes white space inside a string to be retained
[
confix_p
(
'"',
*lex_escape_ch_p,
'"'
)
]
;
number_
= strict_real_p[ new_real ]
| int64_p [ new_int ]
| uint64_p [ new_uint64 ]
;
}
spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
const spirit_namespace::rule< ScannerT >& start() const { return json_; }
};
private:
Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
Semantic_actions_t& actions_;
};
template< class Iter_type, class Value_type >
Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
{
Semantic_actions< Value_type, Iter_type > semantic_actions( value );
const spirit_namespace::parse_info< Iter_type > info =
spirit_namespace::parse( begin, end,
Json_grammer< Value_type, Iter_type >( semantic_actions ),
spirit_namespace::space_p );
if( !info.hit )
{
assert( false ); // in theory exception should already have been thrown
throw_error( info.stop, "error" );
}
return info.stop;
}
template< class Iter_type, class Value_type >
void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
{
typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
const Posn_iter_t posn_begin( begin, end );
const Posn_iter_t posn_end( end, end );
read_range_or_throw( posn_begin, posn_end, value );
}
template< class Iter_type, class Value_type >
bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
{
try
{
begin = read_range_or_throw( begin, end, value );
return true;
}
catch( ... )
{
return false;
}
}
template< class String_type, class Value_type >
void read_string_or_throw( const String_type& s, Value_type& value )
{
add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
}
template< class String_type, class Value_type >
bool read_string( const String_type& s, Value_type& value )
{
typename String_type::const_iterator begin = s.begin();
return read_range( begin, s.end(), value );
}
template< class Istream_type >
struct Multi_pass_iters
{
typedef typename Istream_type::char_type Char_type;
typedef std::istream_iterator< Char_type, Char_type > istream_iter;
typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
Multi_pass_iters( Istream_type& is )
{
is.unsetf( std::ios::skipws );
begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
end_ = spirit_namespace::make_multi_pass( istream_iter() );
}
Mp_iter begin_;
Mp_iter end_;
};
template< class Istream_type, class Value_type >
bool read_stream( Istream_type& is, Value_type& value )
{
Multi_pass_iters< Istream_type > mp_iters( is );
return read_range( mp_iters.begin_, mp_iters.end_, value );
}
template< class Istream_type, class Value_type >
void read_stream_or_throw( Istream_type& is, Value_type& value )
{
const Multi_pass_iters< Istream_type > mp_iters( is );
add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
}
}
#endif

70
json_spirit/json_spirit_stream_reader.h

@ -0,0 +1,70 @@
#ifndef JSON_SPIRIT_READ_STREAM
#define JSON_SPIRIT_READ_STREAM
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include "json_spirit_reader_template.h"
namespace json_spirit
{
// these classes allows you to read multiple top level contiguous values from a stream,
// the normal stream read functions have a bug that prevent multiple top level values
// from being read unless they are separated by spaces
template< class Istream_type, class Value_type >
class Stream_reader
{
public:
Stream_reader( Istream_type& is )
: iters_( is )
{
}
bool read_next( Value_type& value )
{
return read_range( iters_.begin_, iters_.end_, value );
}
private:
typedef Multi_pass_iters< Istream_type > Mp_iters;
Mp_iters iters_;
};
template< class Istream_type, class Value_type >
class Stream_reader_thrower
{
public:
Stream_reader_thrower( Istream_type& is )
: iters_( is )
, posn_begin_( iters_.begin_, iters_.end_ )
, posn_end_( iters_.end_, iters_.end_ )
{
}
void read_next( Value_type& value )
{
posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value );
}
private:
typedef Multi_pass_iters< Istream_type > Mp_iters;
typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t;
Mp_iters iters_;
Posn_iter_t posn_begin_, posn_end_;
};
}
#endif

61
json_spirit/json_spirit_utils.h

@ -0,0 +1,61 @@
#ifndef JSON_SPIRIT_UTILS
#define JSON_SPIRIT_UTILS
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include "json_spirit_value.h"
#include <map>
namespace json_spirit
{
template< class Obj_t, class Map_t >
void obj_to_map( const Obj_t& obj, Map_t& mp_obj )
{
mp_obj.clear();
for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i )
{
mp_obj[ i->name_ ] = i->value_;
}
}
template< class Obj_t, class Map_t >
void map_to_obj( const Map_t& mp_obj, Obj_t& obj )
{
obj.clear();
for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i )
{
obj.push_back( typename Obj_t::value_type( i->first, i->second ) );
}
}
typedef std::map< std::string, Value > Mapped_obj;
#ifndef BOOST_NO_STD_WSTRING
typedef std::map< std::wstring, wValue > wMapped_obj;
#endif
template< class Object_type, class String_type >
const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name )
{
for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
{
if( i->name_ == name )
{
return i->value_;
}
}
return Object_type::value_type::Value_type::null;
}
}
#endif

8
json_spirit/json_spirit_value.cpp

@ -0,0 +1,8 @@
/* Copyright (c) 2007 John W Wilkinson
This source code can be used for any purpose as long as
this comment is retained. */
// json spirit version 2.00
#include "json_spirit_value.h"

532
json_spirit/json_spirit_value.h

@ -0,0 +1,532 @@
#ifndef JSON_SPIRIT_VALUE
#define JSON_SPIRIT_VALUE
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <vector>
#include <map>
#include <string>
#include <cassert>
#include <sstream>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/variant.hpp>
namespace json_spirit
{
enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
template< class Config > // Config determines whether the value uses std::string or std::wstring and
// whether JSON Objects are represented as vectors or maps
class Value_impl
{
public:
typedef Config Config_type;
typedef typename Config::String_type String_type;
typedef typename Config::Object_type Object;
typedef typename Config::Array_type Array;
typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
Value_impl(); // creates null value
Value_impl( Const_str_ptr value );
Value_impl( const String_type& value );
Value_impl( const Object& value );
Value_impl( const Array& value );
Value_impl( bool value );
Value_impl( int value );
Value_impl( boost::int64_t value );
Value_impl( boost::uint64_t value );
Value_impl( double value );
Value_impl( const Value_impl& other );
bool operator==( const Value_impl& lhs ) const;
Value_impl& operator=( const Value_impl& lhs );
Value_type type() const;
bool is_uint64() const;
bool is_null() const;
const String_type& get_str() const;
const Object& get_obj() const;
const Array& get_array() const;
bool get_bool() const;
int get_int() const;
boost::int64_t get_int64() const;
boost::uint64_t get_uint64() const;
double get_real() const;
Object& get_obj();
Array& get_array();
template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
// or double d = value.get_value< double >();
static const Value_impl null;
private:
void check_type( const Value_type vtype ) const;
typedef boost::variant< String_type,
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
bool, boost::int64_t, double > Variant;
Value_type type_;
Variant v_;
bool is_uint64_;
};
// vector objects
template< class Config >
struct Pair_impl
{
typedef typename Config::String_type String_type;
typedef typename Config::Value_type Value_type;
Pair_impl( const String_type& name, const Value_type& value );
bool operator==( const Pair_impl& lhs ) const;
String_type name_;
Value_type value_;
};
template< class String >
struct Config_vector
{
typedef String String_type;
typedef Value_impl< Config_vector > Value_type;
typedef Pair_impl < Config_vector > Pair_type;
typedef std::vector< Value_type > Array_type;
typedef std::vector< Pair_type > Object_type;
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
{
obj.push_back( Pair_type( name , value ) );
return obj.back().value_;
}
static String_type get_name( const Pair_type& pair )
{
return pair.name_;
}
static Value_type get_value( const Pair_type& pair )
{
return pair.value_;
}
};
// typedefs for ASCII
typedef Config_vector< std::string > Config;
typedef Config::Value_type Value;
typedef Config::Pair_type Pair;
typedef Config::Object_type Object;
typedef Config::Array_type Array;
// typedefs for Unicode
#ifndef BOOST_NO_STD_WSTRING
typedef Config_vector< std::wstring > wConfig;
typedef wConfig::Value_type wValue;
typedef wConfig::Pair_type wPair;
typedef wConfig::Object_type wObject;
typedef wConfig::Array_type wArray;
#endif
// map objects
template< class String >
struct Config_map
{
typedef String String_type;
typedef Value_impl< Config_map > Value_type;
typedef std::vector< Value_type > Array_type;
typedef std::map< String_type, Value_type > Object_type;
typedef typename Object_type::value_type Pair_type;
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
{
return obj[ name ] = value;
}
static String_type get_name( const Pair_type& pair )
{
return pair.first;
}
static Value_type get_value( const Pair_type& pair )
{
return pair.second;
}
};
// typedefs for ASCII
typedef Config_map< std::string > mConfig;
typedef mConfig::Value_type mValue;
typedef mConfig::Object_type mObject;
typedef mConfig::Array_type mArray;
// typedefs for Unicode
#ifndef BOOST_NO_STD_WSTRING
typedef Config_map< std::wstring > wmConfig;
typedef wmConfig::Value_type wmValue;
typedef wmConfig::Object_type wmObject;
typedef wmConfig::Array_type wmArray;
#endif
///////////////////////////////////////////////////////////////////////////////////////////////
//
// implementation
template< class Config >
const Value_impl< Config > Value_impl< Config >::null;
template< class Config >
Value_impl< Config >::Value_impl()
: type_( null_type )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( const Const_str_ptr value )
: type_( str_type )
, v_( String_type( value ) )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( const String_type& value )
: type_( str_type )
, v_( value )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( const Object& value )
: type_( obj_type )
, v_( value )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( const Array& value )
: type_( array_type )
, v_( value )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( bool value )
: type_( bool_type )
, v_( value )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( int value )
: type_( int_type )
, v_( static_cast< boost::int64_t >( value ) )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( boost::int64_t value )
: type_( int_type )
, v_( value )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( boost::uint64_t value )
: type_( int_type )
, v_( static_cast< boost::int64_t >( value ) )
, is_uint64_( true )
{
}
template< class Config >
Value_impl< Config >::Value_impl( double value )
: type_( real_type )
, v_( value )
, is_uint64_( false )
{
}
template< class Config >
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
: type_( other.type() )
, v_( other.v_ )
, is_uint64_( other.is_uint64_ )
{
}
template< class Config >
Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
{
Value_impl tmp( lhs );
std::swap( type_, tmp.type_ );
std::swap( v_, tmp.v_ );
std::swap( is_uint64_, tmp.is_uint64_ );
return *this;
}
template< class Config >
bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
{
if( this == &lhs ) return true;
if( type() != lhs.type() ) return false;
return v_ == lhs.v_;
}
template< class Config >
Value_type Value_impl< Config >::type() const
{
return type_;
}
template< class Config >
bool Value_impl< Config >::is_uint64() const
{
return is_uint64_;
}
template< class Config >
bool Value_impl< Config >::is_null() const
{
return type() == null_type;
}
template< class Config >
void Value_impl< Config >::check_type( const Value_type vtype ) const
{
if( type() != vtype )
{
std::ostringstream os;
os << "value type is " << type() << " not " << vtype;
throw std::runtime_error( os.str() );
}
}
template< class Config >
const typename Config::String_type& Value_impl< Config >::get_str() const
{
check_type( str_type );
return *boost::get< String_type >( &v_ );
}
template< class Config >
const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
{
check_type( obj_type );
return *boost::get< Object >( &v_ );
}
template< class Config >
const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
{
check_type( array_type );
return *boost::get< Array >( &v_ );
}
template< class Config >
bool Value_impl< Config >::get_bool() const
{
check_type( bool_type );
return boost::get< bool >( v_ );
}
template< class Config >
int Value_impl< Config >::get_int() const
{
check_type( int_type );
return static_cast< int >( get_int64() );
}
template< class Config >
boost::int64_t Value_impl< Config >::get_int64() const
{
check_type( int_type );
return boost::get< boost::int64_t >( v_ );
}
template< class Config >
boost::uint64_t Value_impl< Config >::get_uint64() const
{
check_type( int_type );
return static_cast< boost::uint64_t >( get_int64() );
}
template< class Config >
double Value_impl< Config >::get_real() const
{
if( type() == int_type )
{
return is_uint64() ? static_cast< double >( get_uint64() )
: static_cast< double >( get_int64() );
}
check_type( real_type );
return boost::get< double >( v_ );
}
template< class Config >
typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
{
check_type( obj_type );
return *boost::get< Object >( &v_ );
}
template< class Config >
typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
{
check_type( array_type );
return *boost::get< Array >( &v_ );
}
template< class Config >
Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
: name_( name )
, value_( value )
{
}
template< class Config >
bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
{
if( this == &lhs ) return true;
return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
}
// converts a C string, ie. 8 bit char array, to a string object
//
template < class String_type >
String_type to_str( const char* c_str )
{
String_type result;
for( const char* p = c_str; *p != 0; ++p )
{
result += *p;
}
return result;
}
//
namespace internal_
{
template< typename T >
struct Type_to_type
{
};
template< class Value >
int get_value( const Value& value, Type_to_type< int > )
{
return value.get_int();
}
template< class Value >
boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
{
return value.get_int64();
}
template< class Value >
boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
{
return value.get_uint64();
}
template< class Value >
double get_value( const Value& value, Type_to_type< double > )
{
return value.get_real();
}
template< class Value >
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
{
return value.get_str();
}
template< class Value >
typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
{
return value.get_array();
}
template< class Value >
typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
{
return value.get_obj();
}
template< class Value >
bool get_value( const Value& value, Type_to_type< bool > )
{
return value.get_bool();
}
}
template< class Config >
template< typename T >
T Value_impl< Config >::get_value() const
{
return internal_::get_value( *this, internal_::Type_to_type< T >() );
}
}
#endif

95
json_spirit/json_spirit_writer.cpp

@ -0,0 +1,95 @@
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#include "json_spirit_writer.h"
#include "json_spirit_writer_template.h"
void json_spirit::write( const Value& value, std::ostream& os )
{
write_stream( value, os, false );
}
void json_spirit::write_formatted( const Value& value, std::ostream& os )
{
write_stream( value, os, true );
}
std::string json_spirit::write( const Value& value )
{
return write_string( value, false );
}
std::string json_spirit::write_formatted( const Value& value )
{
return write_string( value, true );
}
#ifndef BOOST_NO_STD_WSTRING
void json_spirit::write( const wValue& value, std::wostream& os )
{
write_stream( value, os, false );
}
void json_spirit::write_formatted( const wValue& value, std::wostream& os )
{
write_stream( value, os, true );
}
std::wstring json_spirit::write( const wValue& value )
{
return write_string( value, false );
}
std::wstring json_spirit::write_formatted( const wValue& value )
{
return write_string( value, true );
}
#endif
void json_spirit::write( const mValue& value, std::ostream& os )
{
write_stream( value, os, false );
}
void json_spirit::write_formatted( const mValue& value, std::ostream& os )
{
write_stream( value, os, true );
}
std::string json_spirit::write( const mValue& value )
{
return write_string( value, false );
}
std::string json_spirit::write_formatted( const mValue& value )
{
return write_string( value, true );
}
#ifndef BOOST_NO_STD_WSTRING
void json_spirit::write( const wmValue& value, std::wostream& os )
{
write_stream( value, os, false );
}
void json_spirit::write_formatted( const wmValue& value, std::wostream& os )
{
write_stream( value, os, true );
}
std::wstring json_spirit::write( const wmValue& value )
{
return write_string( value, false );
}
std::wstring json_spirit::write_formatted( const wmValue& value )
{
return write_string( value, true );
}
#endif

50
json_spirit/json_spirit_writer.h

@ -0,0 +1,50 @@
#ifndef JSON_SPIRIT_WRITER
#define JSON_SPIRIT_WRITER
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include "json_spirit_value.h"
#include <iostream>
namespace json_spirit
{
// functions to convert JSON Values to text,
// the "formatted" versions add whitespace to format the output nicely
void write ( const Value& value, std::ostream& os );
void write_formatted( const Value& value, std::ostream& os );
std::string write ( const Value& value );
std::string write_formatted( const Value& value );
#ifndef BOOST_NO_STD_WSTRING
void write ( const wValue& value, std::wostream& os );
void write_formatted( const wValue& value, std::wostream& os );
std::wstring write ( const wValue& value );
std::wstring write_formatted( const wValue& value );
#endif
void write ( const mValue& value, std::ostream& os );
void write_formatted( const mValue& value, std::ostream& os );
std::string write ( const mValue& value );
std::string write_formatted( const mValue& value );
#ifndef BOOST_NO_STD_WSTRING
void write ( const wmValue& value, std::wostream& os );
void write_formatted( const wmValue& value, std::wostream& os );
std::wstring write ( const wmValue& value );
std::wstring write_formatted( const wmValue& value );
#endif
}
#endif

248
json_spirit/json_spirit_writer_template.h

@ -0,0 +1,248 @@
#ifndef JSON_SPIRIT_WRITER_TEMPLATE
#define JSON_SPIRIT_WRITER_TEMPLATE
// Copyright John W. Wilkinson 2007 - 2009.
// Distributed under the MIT License, see accompanying file LICENSE.txt
// json spirit version 4.03
#include "json_spirit_value.h"
#include <cassert>
#include <sstream>
#include <iomanip>
namespace json_spirit
{
inline char to_hex_char( unsigned int c )
{
assert( c <= 0xF );
const char ch = static_cast< char >( c );
if( ch < 10 ) return '0' + ch;
return 'A' - 10 + ch;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs")
template< class String_type >
String_type non_printable_to_string( unsigned int c )
{
typedef typename String_type::value_type Char_type;
String_type result( 6, '\\' );
result[1] = 'u';
result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
result[ 2 ] = to_hex_char( c & 0x000F );
return result;
}
#pragma GCC diagnostic pop
template< typename Char_type, class String_type >
bool add_esc_char( Char_type c, String_type& s )
{
switch( c )
{
case '"': s += to_str< String_type >( "\\\"" ); return true;
case '\\': s += to_str< String_type >( "\\\\" ); return true;
case '\b': s += to_str< String_type >( "\\b" ); return true;
case '\f': s += to_str< String_type >( "\\f" ); return true;
case '\n': s += to_str< String_type >( "\\n" ); return true;
case '\r': s += to_str< String_type >( "\\r" ); return true;
case '\t': s += to_str< String_type >( "\\t" ); return true;
}
return false;
}
template< class String_type >
String_type add_esc_chars( const String_type& s )
{
typedef typename String_type::const_iterator Iter_type;
typedef typename String_type::value_type Char_type;
String_type result;
const Iter_type end( s.end() );
for( Iter_type i = s.begin(); i != end; ++i )
{
const Char_type c( *i );
if( add_esc_char( c, result ) ) continue;
const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
if( iswprint( unsigned_c ) )
{
result += c;
}
else
{
result += non_printable_to_string< String_type >( unsigned_c );
}
}
return result;
}
// this class generates the JSON text,
// it keeps track of the indentation level etc.
//
template< class Value_type, class Ostream_type >
class Generator
{
typedef typename Value_type::Config_type Config_type;
typedef typename Config_type::String_type String_type;
typedef typename Config_type::Object_type Object_type;
typedef typename Config_type::Array_type Array_type;
typedef typename String_type::value_type Char_type;
typedef typename Object_type::value_type Obj_member_type;
public:
Generator( const Value_type& value, Ostream_type& os, bool pretty )
: os_( os )
, indentation_level_( 0 )
, pretty_( pretty )
{
output( value );
}
private:
void output( const Value_type& value )
{
switch( value.type() )
{
case obj_type: output( value.get_obj() ); break;
case array_type: output( value.get_array() ); break;
case str_type: output( value.get_str() ); break;
case bool_type: output( value.get_bool() ); break;
case int_type: output_int( value ); break;
case real_type: os_ << std::showpoint << std::setprecision( 16 )
<< value.get_real(); break;
case null_type: os_ << "null"; break;
default: assert( false );
}
}
void output( const Object_type& obj )
{
output_array_or_obj( obj, '{', '}' );
}
void output( const Array_type& arr )
{
output_array_or_obj( arr, '[', ']' );
}
void output( const Obj_member_type& member )
{
output( Config_type::get_name( member ) ); space();
os_ << ':'; space();
output( Config_type::get_value( member ) );
}
void output_int( const Value_type& value )
{
if( value.is_uint64() )
{
os_ << value.get_uint64();
}
else
{
os_ << value.get_int64();
}
}
void output( const String_type& s )
{
os_ << '"' << add_esc_chars( s ) << '"';
}
void output( bool b )
{
os_ << to_str< String_type >( b ? "true" : "false" );
}
template< class T >
void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
{
os_ << start_char; new_line();
++indentation_level_;
for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
{
indent(); output( *i );
typename T::const_iterator next = i;
if( ++next != t.end())
{
os_ << ',';
}
new_line();
}
--indentation_level_;
indent(); os_ << end_char;
}
void indent()
{
if( !pretty_ ) return;
for( int i = 0; i < indentation_level_; ++i )
{
os_ << " ";
}
}
void space()
{
if( pretty_ ) os_ << ' ';
}
void new_line()
{
if( pretty_ ) os_ << '\n';
}
Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
Ostream_type& os_;
int indentation_level_;
bool pretty_;
};
template< class Value_type, class Ostream_type >
void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
{
Generator< Value_type, Ostream_type >( value, os, pretty );
}
template< class Value_type >
typename Value_type::String_type write_string( const Value_type& value, bool pretty )
{
typedef typename Value_type::String_type::value_type Char_type;
std::basic_ostringstream< Char_type > os;
write_stream( value, os, pretty );
return os.str();
}
}
#endif

27
libethereum/AddressState.h

@ -37,9 +37,24 @@ enum class AddressType
class AddressState
{
public:
AddressState(): m_type(AddressType::Dead), m_balance(0), m_nonce(0) {}
AddressState(u256 _balance, u256 _nonce): m_type(AddressType::Normal), m_balance(_balance), m_nonce(_nonce) {}
AddressState(u256 _balance, u256 _nonce, h256 _contractRoot): m_type(AddressType::Contract), m_balance(_balance), m_nonce(_nonce), m_contractRoot(_contractRoot) {}
AddressState(): m_type(AddressType::Dead), m_balance(0), m_nonce(0), m_haveMemory(false) {}
AddressState(u256 _balance, u256 _nonce, AddressType _type = AddressType::Normal): m_type(_type), m_balance(_balance), m_nonce(_nonce), m_haveMemory(true) {}
AddressState(u256 _balance, u256 _nonce, h256 _contractRoot): m_type(AddressType::Contract), m_balance(_balance), m_nonce(_nonce), m_haveMemory(false), m_contractRoot(_contractRoot) {}
AddressState(u256 _balance, u256 _nonce, u256s _memory): m_type(AddressType::Contract), m_balance(_balance), m_nonce(_nonce), m_haveMemory(true)
{
for (unsigned i = 0; i < _memory.size(); ++i)
#ifdef __clang__
{
auto mFinder = m_memory.find((u256)i);
if (mFinder == m_memory.end())
m_memory.insert(std::make_pair((u256)i,_memory[i]));
else
mFinder->second = _memory[i];
}
#else
m_memory[(u256)i] = _memory[i];
#endif
}
void incNonce() { m_nonce++; }
void addBalance(bigint _i) { m_balance = (u256)((bigint)m_balance + _i); }
@ -50,15 +65,17 @@ public:
u256 const& balance() const { return m_balance; }
u256& nonce() { return m_nonce; }
u256 const& nonce() const { return m_nonce; }
bool haveMemory() const { return m_memory.empty() && m_contractRoot != h256(); } // TODO: best to switch to m_haveMemory flag rather than try to infer.
bool haveMemory() const { return m_haveMemory; }
std::map<u256, u256>& setHaveMemory() { assert(m_type == AddressType::Contract); m_haveMemory = true; m_contractRoot = h256(); return m_memory; }
h256 oldRoot() const { assert(!haveMemory()); return m_contractRoot; }
std::map<u256, u256>& takeMemory() { assert(m_type == AddressType::Contract && haveMemory()); m_contractRoot = h256(); return m_memory; }
std::map<u256, u256>& memory() { assert(m_type == AddressType::Contract && haveMemory()); return m_memory; }
std::map<u256, u256> const& memory() const { assert(m_type == AddressType::Contract && haveMemory()); return m_memory; }
private:
AddressType m_type;
u256 m_balance;
u256 m_nonce;
bool m_haveMemory;
h256 m_contractRoot;
// TODO: change to unordered_map.
std::map<u256, u256> m_memory;

41
libethereum/BlockChain.cpp

@ -33,6 +33,8 @@
using namespace std;
using namespace eth;
#define ETH_CATCH 1
namespace eth
{
std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc)
@ -116,20 +118,41 @@ bool contains(T const& _t, V const& _v)
return false;
}
bool BlockChain::attemptImport(bytes const& _block, Overlay const& _stateDB)
{
#if ETH_CATCH
try
#endif
{
import(_block, _stateDB);
return true;
}
#if ETH_CATCH
catch (...)
{
return false;
}
#endif
}
void BlockChain::import(bytes const& _block, Overlay const& _db)
{
// VERIFY: populates from the block and checks the block is internally coherent.
BlockInfo bi(&_block);
#if ETH_CATCH
try
#endif
{
bi.verifyInternals(&_block);
}
#if ETH_CATCH
catch (Exception const& _e)
{
clog(BlockChainNote) << " Malformed block (" << _e.description() << ").";
throw;
}
#endif
auto newHash = eth::sha3(_block);
// Check block doesn't already exist first!
@ -151,7 +174,9 @@ void BlockChain::import(bytes const& _block, Overlay const& _db)
clog(BlockChainNote) << "Attempting import of " << newHash << "...";
u256 td;
#if ETH_CATCH
try
#endif
{
// Check family:
BlockInfo biParent(block(bi.parentHash));
@ -168,7 +193,7 @@ void BlockChain::import(bytes const& _block, Overlay const& _db)
auto tdIncrease = s.playback(&_block, bi, biParent, biGrandParent, true);
td = pd.totalDifficulty + tdIncrease;
#if PARANOIA
#if ETH_PARANOIA
checkConsistency();
#endif
// All ok - insert into DB
@ -182,15 +207,17 @@ void BlockChain::import(bytes const& _block, Overlay const& _db)
m_detailsDB->Put(m_writeOptions, ldb::Slice((char const*)&bi.parentHash, 32), (ldb::Slice)eth::ref(m_details[bi.parentHash].rlp()));
m_db->Put(m_writeOptions, ldb::Slice((char const*)&newHash, 32), (ldb::Slice)ref(_block));
#if PARANOIA
#if ETH_PARANOIA
checkConsistency();
#endif
}
catch (...)
#if ETH_CATCH
catch (Exception const& _e)
{
clog(BlockChainNote) << " Malformed block.";
clog(BlockChainNote) << " Malformed block (" << _e.description() << ").";
throw;
}
#endif
// cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children.";
@ -244,7 +271,7 @@ bytesConstRef BlockChain::block(h256 _hash) const
BlockDetails const& BlockChain::details(h256 _h) const
{
std::map<h256, BlockDetails>::const_iterator it;
BlockDetailsHash::const_iterator it;
bool fetchRequired;
{
lock_guard<mutex> l(m_lock);
@ -263,7 +290,7 @@ BlockDetails const& BlockChain::details(h256 _h) const
{
lock_guard<mutex> l(m_lock);
bool ok;
tie(it, ok) = m_details.insert(make_pair(_h, BlockDetails(RLP(s))));
tie(it, ok) = m_details.insert(std::make_pair(_h, BlockDetails(RLP(s))));
}
}
return it->second;

12
libethereum/BlockChain.h

@ -48,6 +48,8 @@ struct BlockDetails
h256s children;
};
typedef std::map<h256, BlockDetails> BlockDetailsHash;
static const BlockDetails NullBlockDetails;
static const h256s NullH256s;
@ -56,8 +58,8 @@ class Overlay;
class AlreadyHaveBlock: public std::exception {};
class UnknownParent: public std::exception {};
struct BlockChainChat: public LogChannel { static const char constexpr* name = "-B-"; static const int verbosity = 7; };
struct BlockChainNote: public LogChannel { static const char constexpr* name = "=B="; static const int verbosity = 4; };
struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; };
struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; };
/**
* @brief Implements the blockchain database. All data this gives is disk-backed.
@ -72,9 +74,9 @@ public:
/// (Potentially) renders invalid existing bytesConstRef returned by lastBlock.
/// To be called from main loop every 100ms or so.
void process();
/// Attempt to import the given block.
bool attemptImport(bytes const& _block, Overlay const& _stateDB) { try { import(_block, _stateDB); return true; } catch (...) { return false; } }
bool attemptImport(bytes const& _block, Overlay const& _stateDB);
/// Import block into disk-backed DB
void import(bytes const& _block, Overlay const& _stateDB);
@ -101,7 +103,7 @@ private:
void checkConsistency();
/// Get fully populated from disk DB.
mutable std::map<h256, BlockDetails> m_details;
mutable BlockDetailsHash m_details;
mutable std::map<h256, std::string> m_cache;
mutable std::mutex m_lock;

4
libethereum/BlockInfo.cpp

@ -101,7 +101,7 @@ void BlockInfo::populateFromHeader(RLP const& _header)
extraData = _header[field = 7].toBytes();
nonce = _header[field = 8].toHash<h256>();
}
catch (RLP::BadCast)
catch (RLPException const&)
{
throw InvalidBlockHeaderFormat(field, _header[field].data());
}
@ -152,6 +152,6 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const
throw InvalidDifficulty();
// Check timestamp is after previous timestamp.
if (parentHash && _parent.timestamp >= timestamp)
if (parentHash && _parent.timestamp > timestamp)
throw InvalidTimestamp();
}

79
libethereum/Client.cpp

@ -32,63 +32,63 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const
m_clientVersion(_clientVersion),
m_bc(_dbPath),
m_stateDB(State::openDB(_dbPath)),
m_s(_us, m_stateDB),
m_mined(_us, m_stateDB)
m_preMine(_us, m_stateDB),
m_postMine(_us, m_stateDB),
m_workState(Active)
{
Defaults::setDBPath(_dbPath);
// Synchronise the state according to the block chain - i.e. replay all transactions in block chain, in order.
// In practise this won't need to be done since the State DB will contain the keys for the tries for most recent (and many old) blocks.
// Synchronise the state according to the head of the block chain.
// TODO: currently it contains keys for *all* blocks. Make it remove old ones.
m_s.sync(m_bc);
m_s.sync(m_tq);
m_mined = m_s;
m_preMine.sync(m_bc);
m_postMine = m_preMine;
m_changed = true;
static const char* c_threadName = "eth";
m_work = new thread([&](){
m_work.reset(new thread([&](){
setThreadName(c_threadName);
while (m_workState != Deleting) work(); m_workState = Deleted;
});
while (m_workState.load(std::memory_order_acquire) != Deleting)
work();
m_workState.store(Deleted, std::memory_order_release);
}));
}
Client::~Client()
{
if (m_workState == Active)
m_workState = Deleting;
while (m_workState != Deleted)
if (m_workState.load(std::memory_order_acquire) == Active)
m_workState.store(Deleting, std::memory_order_release);
while (m_workState.load(std::memory_order_acquire) != Deleted)
this_thread::sleep_for(chrono::milliseconds(10));
m_work->join();
}
void Client::startNetwork(short _listenPort, std::string const& _seedHost, short _port, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp)
void Client::startNetwork(unsigned short _listenPort, std::string const& _seedHost, unsigned short _port, NodeMode _mode, unsigned _peers, string const& _publicIP, bool _upnp)
{
if (m_net)
if (m_net.get())
return;
m_net = new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp);
m_net.reset(new PeerServer(m_clientVersion, m_bc, 0, _listenPort, _mode, _publicIP, _upnp));
m_net->setIdealPeerCount(_peers);
if (_seedHost.size())
connect(_seedHost, _port);
}
void Client::connect(std::string const& _seedHost, short _port)
void Client::connect(std::string const& _seedHost, unsigned short _port)
{
if (!m_net)
if (!m_net.get())
return;
m_net->connect(_seedHost, _port);
}
void Client::stopNetwork()
{
delete m_net;
m_net = nullptr;
m_net.reset(nullptr);
}
void Client::startMining()
{
m_doMine = true;
m_miningStarted = true;
m_restartMining = true;
}
void Client::stopMining()
@ -98,9 +98,9 @@ void Client::stopMining()
void Client::transact(Secret _secret, Address _dest, u256 _amount, u256s _data)
{
lock_guard<mutex> l(m_lock);
lock_guard<recursive_mutex> l(m_lock);
Transaction t;
t.nonce = m_mined.transactionsFrom(toAddress(_secret));
t.nonce = m_postMine.transactionsFrom(toAddress(_secret));
t.receiveAddress = _dest;
t.value = _amount;
t.data = _data;
@ -121,7 +121,7 @@ void Client::work()
{
m_net->process();
lock_guard<mutex> l(m_lock);
lock_guard<recursive_mutex> l(m_lock);
if (m_net->sync(m_bc, m_tq, m_stateDB))
changed = true;
}
@ -134,36 +134,36 @@ void Client::work()
// all blocks.
// Resynchronise state with block chain & trans
{
lock_guard<mutex> l(m_lock);
if (m_s.sync(m_bc))
lock_guard<recursive_mutex> l(m_lock);
if (m_preMine.sync(m_bc) || m_postMine.address() != m_preMine.address())
{
if (m_doMine)
cnote << "Externally mined block: Restarting mining operation.";
cnote << "New block on chain: Restarting mining operation.";
changed = true;
m_miningStarted = true; // need to re-commit to mine.
m_mined = m_s;
m_restartMining = true; // need to re-commit to mine.
m_postMine = m_preMine;
}
if (m_mined.sync(m_tq))
if (m_postMine.sync(m_tq))
{
if (m_doMine)
cnote << "Additional transaction ready: Restarting mining operation.";
changed = true;
m_miningStarted = true;
m_restartMining = true;
}
}
if (m_doMine)
{
if (m_miningStarted)
if (m_restartMining)
{
lock_guard<mutex> l(m_lock);
m_mined.commitToMine(m_bc);
lock_guard<recursive_mutex> l(m_lock);
m_postMine.commitToMine(m_bc);
}
m_miningStarted = false;
m_restartMining = false;
// Mine for a while.
MineInfo mineInfo = m_mined.mine(100);
MineInfo mineInfo = m_postMine.mine(100);
m_mineProgress.best = max(m_mineProgress.best, mineInfo.best);
m_mineProgress.current = mineInfo.best;
m_mineProgress.requirement = mineInfo.requirement;
@ -171,11 +171,10 @@ void Client::work()
if (mineInfo.completed)
{
// Import block.
lock_guard<mutex> l(m_lock);
m_bc.attemptImport(m_mined.blockData(), m_stateDB);
lock_guard<recursive_mutex> l(m_lock);
m_bc.attemptImport(m_postMine.blockData(), m_stateDB);
m_mineProgress.best = 0;
m_changed = true;
m_miningStarted = true; // need to re-commit to mine.
}
}
else

40
libethereum/Client.h

@ -23,6 +23,7 @@
#include <thread>
#include <mutex>
#include <atomic>
#include "Common.h"
#include "BlockChain.h"
#include "TransactionQueue.h"
@ -52,6 +53,13 @@ private:
Client* m_client;
};
enum ClientWorkState
{
Active = 0,
Deleting,
Deleted
};
class Client
{
public:
@ -90,11 +98,13 @@ public:
bool changed() const { auto ret = m_changed; m_changed = false; return ret; }
/// Get the object representing the current state of Ethereum.
State const& state() const { return m_s; }
State const& state() const { return m_preMine; }
/// Get the object representing the current state of Ethereum.
State const& postState() const { return m_postMine; }
/// Get the object representing the current canonical blockchain.
BlockChain const& blockChain() const { return m_bc; }
/// Get a map containing each of the pending transactions.
std::map<h256, Transaction> const& pending() const { return m_mined.pending(); }
Transactions const& pending() const { return m_postMine.pending(); }
void setClientVersion(std::string const& _name) { m_clientVersion = _name; }
@ -103,23 +113,23 @@ public:
/// Get information on the current peer set.
std::vector<PeerInfo> peers() { return m_net ? m_net->peers() : std::vector<PeerInfo>(); }
/// Same as peers().size(), but more efficient.
unsigned peerCount() const { return m_net ? m_net->peerCount() : 0; }
size_t peerCount() const { return m_net ? m_net->peerCount() : 0; }
/// Start the network subsystem.
void startNetwork(short _listenPort = 30303, std::string const& _seedHost = std::string(), short _port = 30303, NodeMode _mode = NodeMode::Full, unsigned _peers = 5, std::string const& _publicIP = std::string(), bool _upnp = true);
void startNetwork(unsigned short _listenPort = 30303, std::string const& _remoteHost = std::string(), unsigned short _remotePort = 30303, NodeMode _mode = NodeMode::Full, unsigned _peers = 5, std::string const& _publicIP = std::string(), bool _upnp = true);
/// Connect to a particular peer.
void connect(std::string const& _seedHost, short _port = 30303);
void connect(std::string const& _seedHost, unsigned short _port = 30303);
/// Stop the network subsystem.
void stopNetwork();
/// Get access to the peer server object. This will be null if the network isn't online.
PeerServer* peerServer() const { return m_net; }
PeerServer* peerServer() const { return m_net.get(); }
// Mining stuff:
/// Set the coinbase address.
void setAddress(Address _us) { m_s.setAddress(_us); }
void setAddress(Address _us) { m_preMine.setAddress(_us); }
/// Get the coinbase address.
Address address() const { return m_s.address(); }
Address address() const { return m_preMine.address(); }
/// Start mining.
void startMining();
/// Stop mining.
@ -134,17 +144,17 @@ private:
BlockChain m_bc; ///< Maintains block database.
TransactionQueue m_tq; ///< Maintains list of incoming transactions not yet on the block chain.
Overlay m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it.
State m_s; ///< The present state of the client.
State m_mined; ///< The state of the client which we're mining (i.e. it'll have all the rewards added).
PeerServer* m_net = nullptr; ///< Should run in background and send us events when blocks found and allow us to send blocks as required.
State m_preMine; ///< The present state of the client.
State m_postMine; ///< The state of the client which we're mining (i.e. it'll have all the rewards added).
std::unique_ptr<PeerServer> m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required.
std::thread* m_work; ///< The work thread.
std::unique_ptr<std::thread> m_work;///< The work thread.
std::mutex m_lock;
enum { Active = 0, Deleting, Deleted } m_workState = Active;
std::recursive_mutex m_lock;
std::atomic<ClientWorkState> m_workState;
bool m_doMine = false; ///< Are we supposed to be mining?
MineProgress m_mineProgress;
mutable bool m_miningStarted = false;
mutable bool m_restartMining = false;
mutable bool m_changed;
};

28
libethereum/Common.cpp

@ -21,6 +21,7 @@
#include "Common.h"
#include <fstream>
#include <random>
#if WIN32
#pragma warning(push)
@ -191,13 +192,13 @@ KeyPair KeyPair::create()
{
secp256k1_start();
static std::mt19937_64 s_eng(time(0));
std::uniform_int_distribution<byte> d(0, 255);
std::uniform_int_distribution<uint16_t> d(0, 255);
for (int i = 0; i < 100; ++i)
{
h256 sec;
for (uint i = 0; i < 32; ++i)
sec[i] = d(s_eng);
for (unsigned i = 0; i < 32; ++i)
sec[i] = (byte)d(s_eng);
KeyPair ret(sec);
if (ret.address())
@ -281,3 +282,24 @@ std::string eth::formatBalance(u256 _b)
ret << _b << " wei";
return ret.str();
}
bytes eth::contents(std::string const& _file)
{
std::ifstream is(_file, std::ifstream::binary);
if (!is)
return bytes();
// get length of file:
is.seekg (0, is.end);
streamoff length = is.tellg();
is.seekg (0, is.beg);
bytes ret(length);
is.read((char*)ret.data(), length);
is.close();
return ret;
}
void eth::writeFile(std::string const& _file, bytes const& _data)
{
ofstream(_file, ios::trunc).write((char const*)_data.data(), _data.size());
}

269
libethereum/Common.h

@ -23,15 +23,27 @@
#pragma once
// define version
#define ETH_VERSION 0.3.9
// way to many uint to size_t warnings in 32 bit build
#ifdef _M_IX86
#pragma warning(disable:4244)
#endif
#ifdef _MSC_VER
#define _ALLOW_KEYWORD_MACROS
#define noexcept throw()
#endif
#include <ctime>
#include <chrono>
#include <array>
#include <map>
#include <unordered_map>
#include <set>
#include <array>
#include <list>
#include <set>
#include <string>
#include <cassert>
@ -42,11 +54,13 @@
#include <boost/thread.hpp>
#include "vector_ref.h"
// CryptoPP defines byte in the global namespace, so so must we.
using byte = uint8_t;
namespace eth
{
// Binary data types.
using byte = uint8_t;
using bytes = std::vector<byte>;
using bytesRef = vector_ref<byte>;
using bytesConstRef = vector_ref<byte const>;
@ -79,6 +93,12 @@ std::string asHex(_T const& _data, int _w = 2)
return ret.str();
}
/// Converts a (printable) ASCII hex string into the corresponding byte stream.
/// @example fromUserHex("41626261") == asBytes("Abba")
bytes fromUserHex(std::string const& _s);
template <unsigned T> class UnitTest {};
template <unsigned N>
class FixedHash
{
@ -90,8 +110,9 @@ public:
FixedHash() { m_data.fill(0); }
FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
explicit FixedHash(bytes const& _b) { memcpy(m_data.data(), _b.data(), std::min<uint>(_b.size(), N)); }
explicit FixedHash(bytes const& _b) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min<uint>(_b.size(), N)); }
explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }
explicit FixedHash(std::string const& _user): FixedHash(fromUserHex(_user)) {}
operator Arith() const { return fromBigEndian<Arith>(m_data); }
@ -109,7 +130,7 @@ public:
FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
FixedHash& operator~() { for (auto i = 0; i < N; ++i) m_data[i] = ~m_data[i]; return *this; }
std::string abridged() const { return asHex(ref().cropped(0, 4)); }
std::string abridged() const { return asHex(ref().cropped(0, 4)) + ".."; }
byte& operator[](unsigned _i) { return m_data[_i]; }
byte operator[](unsigned _i) const { return m_data[_i]; }
@ -124,10 +145,42 @@ public:
std::array<byte, N>& asArray() { return m_data; }
std::array<byte, N> const& asArray() const { return m_data; }
// generic std::hash compatible function object
struct hash
{
size_t operator()(FixedHash const& value) const
{
size_t h = 0;
for (auto i: value.m_data)
h = (h << 5 - h) + i;
return h;
}
};
private:
std::array<byte, N> m_data;
};
// fast equality for h256
template<> inline bool FixedHash<32>::operator==(FixedHash<32> const& _other) const
{
const uint64_t* hash1 = (const uint64_t*)this->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
{
const uint64_t*data = (const uint64_t*)value.data();
uint64_t hash = data[0];
hash ^= data[1];
hash ^= data[2];
hash ^= data[3];
return (size_t)hash;
}
template <unsigned N>
inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
{
@ -160,7 +213,6 @@ using HexMap = std::map<bytes, std::string>;
static const u256 Invalid256 = ~(u256)0;
static const bytes NullBytes;
/// Logging
class NullOutputStream
{
@ -179,12 +231,12 @@ struct ThreadLocalLogName
extern ThreadLocalLogName t_logThreadName;
inline void setThreadName(char const* _n) { t_logThreadName.m_name.reset(new std::string(_n)); }
struct LogChannel { static const char constexpr* name = " "; static const int verbosity = 1; };
struct LeftChannel: public LogChannel { static const char constexpr* name = "<<<"; };
struct RightChannel: public LogChannel { static const char constexpr* name = ">>>"; };
struct WarnChannel: public LogChannel { static const char constexpr* name = "!!!"; static const int verbosity = 0; };
struct NoteChannel: public LogChannel { static const char constexpr* name = "***"; };
struct DebugChannel: public LogChannel { static const char constexpr* name = "---"; static const int verbosity = 7; };
struct LogChannel { static const char* name() { return " "; } static const int verbosity = 1; };
struct LeftChannel: public LogChannel { static const char* name() { return "<<<"; } };
struct RightChannel: public LogChannel { static const char* name() { return ">>>"; } };
struct WarnChannel: public LogChannel { static const char* name() { return "!!!"; } static const int verbosity = 0; };
struct NoteChannel: public LogChannel { static const char* name() { return "***"; } };
struct DebugChannel: public LogChannel { static const char* name() { return "---"; } static const int verbosity = 0; };
extern int g_logVerbosity;
extern std::function<void(std::string const&, char const*)> g_logPost;
@ -203,12 +255,12 @@ public:
{
time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
char buf[24];
if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
buf[0] = '\0'; // empty if case strftime fails
sstr << Id::name << " [ " << buf << " | " << *(t_logThreadName.m_name.get()) << (_term ? " ] " : "");
if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
buf[0] = '\0'; // empty if case strftime fails
sstr << Id::name() << " [ " << buf << " | " << *(t_logThreadName.m_name.get()) << (_term ? " ] " : "");
}
}
~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(sstr.str(), Id::name); }
~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(sstr.str(), Id::name()); }
template <class T> LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && sstr.str().size() && sstr.str().back() != ' ') sstr << " "; sstr << _t; } return *this; }
std::stringstream sstr;
};
@ -298,10 +350,6 @@ std::string escaped(std::string const& _s, bool _all = true);
/// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5
int fromHex(char _i);
/// Converts a (printable) ASCII hex string into the corresponding byte stream.
/// @example fromUserHex("41626261") == asBytes("Abba")
bytes fromUserHex(std::string const& _s);
/// Converts a string into the big-endian base-16 stream of integers (NOT ASCII).
/// @example toHex("A")[0] == 4 && toHex("A")[1] == 1
bytes toHex(std::string const& _s);
@ -451,4 +499,189 @@ private:
Address m_address;
};
static const u256 Uether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Vether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000;
static const u256 Dether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000;
static const u256 Nether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Yether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000;
static const u256 Zether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000;
static const u256 Eether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Pether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000000;
static const u256 Tether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000;
static const u256 Gether = (u256(1000000000) * 1000000000) * 1000000000;
static const u256 Mether = (u256(1000000000) * 1000000000) * 1000000;
static const u256 Kether = (u256(1000000000) * 1000000000) * 1000;
static const u256 ether = u256(1000000000) * 1000000000;
static const u256 finney = u256(1000000000) * 1000000;
static const u256 szabo = u256(1000000000) * 1000;
static const u256 Gwei = u256(1000000000);
static const u256 Mwei = u256(1000000);
static const u256 Kwei = u256(1000);
static const u256 wei = u256(1);
// Stream IO
template <class S, class T> struct StreamOut { static S& bypass(S& _out, T const& _t) { _out << _t; return _out; } };
template <class S> struct StreamOut<S, uint8_t> { static S& bypass(S& _out, uint8_t const& _t) { _out << (int)_t; return _out; } };
template <class S, class T>
inline S& streamout(S& _out, std::vector<T> const& _e)
{
_out << "[";
if (!_e.empty())
{
StreamOut<S, T>::bypass(_out, _e.front());
for (auto i = ++_e.begin(); i != _e.end(); ++i)
StreamOut<S, T>::bypass(_out << ",", *i);
}
_out << "]";
return _out;
}
template <class T> inline std::ostream& operator<<(std::ostream& _out, std::vector<T> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T, unsigned Z>
inline S& streamout(S& _out, std::array<T, Z> const& _e)
{
_out << "[";
if (!_e.empty())
{
StreamOut<S, T>::bypass(_out, _e.front());
auto i = _e.begin();
for (++i; i != _e.end(); ++i)
StreamOut<S, T>::bypass(_out << ",", *i);
}
_out << "]";
return _out;
}
template <class T, unsigned Z> inline std::ostream& operator<<(std::ostream& _out, std::array<T, Z> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T, unsigned long Z>
inline S& streamout(S& _out, std::array<T, Z> const& _e)
{
_out << "[";
if (!_e.empty())
{
StreamOut<S, T>::bypass(_out, _e.front());
auto i = _e.begin();
for (++i; i != _e.end(); ++i)
StreamOut<S, T>::bypass(_out << ",", *i);
}
_out << "]";
return _out;
}
template <class T, unsigned long Z> inline std::ostream& operator<<(std::ostream& _out, std::array<T, Z> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T>
inline S& streamout(S& _out, std::list<T> const& _e)
{
_out << "[";
if (!_e.empty())
{
_out << _e.front();
for (auto i = ++_e.begin(); i != _e.end(); ++i)
_out << "," << *i;
}
_out << "]";
return _out;
}
template <class T> inline std::ostream& operator<<(std::ostream& _out, std::list<T> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T, class U>
inline S& streamout(S& _out, std::pair<T, U> const& _e)
{
_out << "(" << _e.first << "," << _e.second << ")";
return _out;
}
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::pair<T, U> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T1, class T2, class T3>
inline S& streamout(S& _out, std::tuple<T1, T2, T3> const& _t)
{
_out << "(" << std::get<0>(_t) << "," << std::get<1>(_t) << "," << std::get<2>(_t) << ")";
return _out;
}
template <class T1, class T2, class T3> inline std::ostream& operator<<(std::ostream& _out, std::tuple<T1, T2, T3> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T, class U>
S& streamout(S& _out, std::map<T, U> const& _v)
{
if (_v.empty())
return _out << "{}";
int i = 0;
for (auto p: _v)
_out << (!(i++) ? "{ " : "; ") << p.first << " => " << p.second;
return _out << " }";
}
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::map<T, U> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T, class U>
S& streamout(S& _out, std::unordered_map<T, U> const& _v)
{
if (_v.empty())
return _out << "{}";
int i = 0;
for (auto p: _v)
_out << (!(i++) ? "{ " : "; ") << p.first << " => " << p.second;
return _out << " }";
}
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::unordered_map<T, U> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T>
S& streamout(S& _out, std::set<T> const& _v)
{
if (_v.empty())
return _out << "{}";
int i = 0;
for (auto p: _v)
_out << (!(i++) ? "{ " : ", ") << p;
return _out << " }";
}
template <class T> inline std::ostream& operator<<(std::ostream& _out, std::set<T> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T>
S& streamout(S& _out, std::multiset<T> const& _v)
{
if (_v.empty())
return _out << "{}";
int i = 0;
for (auto p: _v)
_out << (!(i++) ? "{ " : ", ") << p;
return _out << " }";
}
template <class T> inline std::ostream& operator<<(std::ostream& _out, std::multiset<T> const& _e) { streamout(_out, _e); return _out; }
template <class S, class T, class U>
S& streamout(S& _out, std::multimap<T, U> const& _v)
{
if (_v.empty())
return _out << "{}";
T l;
int i = 0;
for (auto p: _v)
if (!(i++))
_out << "{ " << (l = p.first) << " => " << p.second;
else if (l == p.first)
_out << ", " << p.second;
else
_out << "; " << (l = p.first) << " => " << p.second;
return _out << " }";
}
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::multimap<T, U> const& _e) { streamout(_out, _e); return _out; }
template <class _S, class _T> _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p) { if (_p) _out << "@" << (*_p); else _out << "nullptr"; return _out; }
bytes contents(std::string const& _file);
void writeFile(std::string const& _file, bytes const& _data);
}
namespace std
{
// forward std::hash<eth::h256> to eth::h256::hash
template<> struct hash<eth::h256>: eth::h256::hash {};
}

21
libethereum/Dagger.cpp

@ -1,3 +1,24 @@
/*
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 Dagger.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include <boost/detail/endian.hpp>
#include <chrono>
#include <array>

23
libethereum/Dagger.h

@ -1,3 +1,26 @@
/*
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 Dagger.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*
* Dagger algorithm. Or not.
*/
#pragma once
#include "Common.h"

16
libethereum/Exceptions.h

@ -15,10 +15,18 @@ public:
class BadHexCharacter: public Exception {};
class NotEnoughCash: public Exception {};
class BadInstruction: public Exception {};
class StackTooSmall: public Exception { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };
class OperandOutOfRange: public Exception { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; };
class ExecutionException: public Exception {};
class RLPException: public Exception {};
class BadCast: public RLPException {};
class BadRLP: public RLPException {};
class VMException: public Exception {};
class StepsDone: public VMException {};
class BreakPointHit: public VMException {};
class BadInstruction: public VMException {};
class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };
class OperandOutOfRange: public VMException { public: OperandOutOfRange(u256 _min, u256 _max, u256 _got): mn(_min), mx(_max), got(_got) {} u256 mn; u256 mx; u256 got; };
class NoSuchContract: public Exception {};
class ContractAddressCollision: public Exception {};
class FeeTooSmall: public Exception {};

76
libethereum/ExtVMFace.h

@ -0,0 +1,76 @@
/*
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 ExtVMFace.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include "Common.h"
#include "FeeStructure.h"
#include "BlockInfo.h"
namespace eth
{
struct Transaction;
class ExtVMFace
{
public:
ExtVMFace() {}
ExtVMFace(FeeStructure const& _fees, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, uint _currentNumber):
fees(_fees),
previousBlock(_previousBlock),
currentBlock(_currentBlock),
currentNumber(_currentNumber)
{}
ExtVMFace(Address _myAddress, Address _txSender, u256 _txValue, u256s const& _txData, FeeStructure const& _fees, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, uint _currentNumber):
myAddress(_myAddress),
txSender(_txSender),
txValue(_txValue),
txData(_txData),
fees(_fees),
previousBlock(_previousBlock),
currentBlock(_currentBlock),
currentNumber(_currentNumber)
{}
u256 store(u256 _n) { return 0; }
void setStore(u256 _n, u256 _v) {}
void mktx(Transaction& _t) {}
u256 balance(Address _a) { return 0; }
void payFee(bigint _fee) {}
u256 txCount(Address _a) { return 0; }
u256 extro(Address _a, u256 _pos) { return 0; }
u256 extroPrice(Address _a) { return 0; }
void suicide(Address _a) {}
Address myAddress;
Address txSender;
u256 txValue;
u256s txData;
FeeStructure fees;
BlockInfo previousBlock; ///< The current block's information.
BlockInfo currentBlock; ///< The current block's information.
uint currentNumber;
};
}

49
libethereum/FeeStructure.cpp

@ -0,0 +1,49 @@
/*
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 FeeStructure.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "FeeStructure.h"
using namespace std;
using namespace eth;
u256 const c_stepFee = 1;
u256 const c_dataFee = 20;
u256 const c_memoryFee = 5;
u256 const c_extroFee = 40;
u256 const c_cryptoFee = 20;
u256 const c_newContractFee = 100;
u256 const c_txFee = 100;
void FeeStructure::setMultiplier(u256 _x)
{
m_stepFee = c_stepFee * _x;
m_dataFee = c_dataFee * _x;
m_memoryFee = c_memoryFee * _x;
m_extroFee = c_extroFee * _x;
m_cryptoFee = c_cryptoFee * _x;
m_newContractFee = c_newContractFee * _x;
m_txFee = c_txFee * _x;
}
u256 FeeStructure::multiplier() const
{
return m_stepFee / c_stepFee;
}

43
libethereum/FeeStructure.h

@ -0,0 +1,43 @@
/*
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 FeeStructure.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include "Common.h"
namespace eth
{
struct FeeStructure
{
/// The fee structure. Values yet to be agreed on...
void setMultiplier(u256 _x); ///< The current block multiplier.
u256 multiplier() const;
u256 m_stepFee;
u256 m_dataFee;
u256 m_memoryFee;
u256 m_extroFee;
u256 m_cryptoFee;
u256 m_newContractFee;
u256 m_txFee;
};
}

2
libethereum/FileSystem.cpp

@ -39,7 +39,9 @@ std::string eth::getDataDir()
return (boost::filesystem::path(path) / "Ethereum").string();
else
{
#ifndef _MSC_VER // todo?
cwarn << "getDataDir(): SHGetSpecialFolderPathA() failed.";
#endif
throw std::runtime_error("getDataDir() - SHGetSpecialFolderPathA() failed.");
}
#else

577
libethereum/Instruction.cpp

@ -0,0 +1,577 @@
/*
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 Instruction.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Instruction.h"
#include <boost/algorithm/string.hpp>
#include "Common.h"
using namespace std;
using namespace eth;
static string readQuoted(char const*& o_d, char const* _e)
{
string ret;
bool escaped = 0;
for (++o_d; o_d != _e && (escaped || *o_d != '"'); ++o_d)
if (!escaped && *o_d == '\\')
escaped = true;
else
ret.push_back(*o_d);
if (o_d != _e)
++o_d; // skip last "
return ret;
}
static u256 readNumeric(string _v, bool _quiet)
{
u256 x = 1;
for (auto const& i: units())
if (boost::algorithm::ends_with(_v, i.second))
{
_v = _v.substr(0, _v.size() - i.second.size());
x = i.first;
break;
}
try
{
return x * u256(_v);
}
catch (...)
{
if (!_quiet)
cwarn << "Invalid numeric" << _v;
}
return 0;
}
u256s eth::assemble(std::string const& _code, bool _quiet)
{
u256s ret;
map<string, unsigned> known;
map<unsigned, string> req;
char const* d = _code.data();
char const* e = _code.data() + _code.size();
while (d != e)
{
// skip to next token
for (; d != e && !isalnum(*d) && *d != '_' && *d != ':' && *d != '"'; ++d) {}
if (d == e)
break;
if (*d == '"')
{
string s = readQuoted(d, e);
if (s.size() > 32)
{
if (!_quiet)
cwarn << "String literal > 32 characters. Cropping.";
s.resize(32);
}
h256 valHash;
memcpy(valHash.data(), s.data(), s.size());
memset(valHash.data() + s.size(), 0, 32 - s.size());
ret.push_back((u256)valHash);
}
else
{
char const* s = d;
for (; d != e && (isalnum(*d) || *d == '_' || *d == ':' || *d == '"'); ++d) {}
string t = string(s, d - s);
if (isdigit(t[0]))
ret.push_back(readNumeric(t, _quiet));
else if (t.back() == ':')
known[t.substr(0, t.size() - 1)] = (unsigned)ret.size();
else
{
auto it = c_instructions.find(boost::algorithm::to_upper_copy(t));
if (it != c_instructions.end())
ret.push_back((u256)it->second);
else
{
req[(unsigned)ret.size()] = t;
ret.push_back(0);
}
}
}
}
for (auto i: req)
if (known.count(i.second))
ret[i.first] = known[i.second];
else
if (!_quiet)
cwarn << "Unknown assembler token" << i.second << "at address" << i.first;
return ret;
}
static void appendCode(u256s& o_code, vector<unsigned>& o_locs, u256s _code, vector<unsigned>& _locs)
{
o_locs.reserve(o_locs.size() + _locs.size());
for (auto i: _locs)
{
_code[i] += (u256)o_code.size();
o_locs.push_back(i + (unsigned)o_code.size());
}
o_code.reserve(o_code.size() + _code.size());
for (auto i: _code)
o_code.push_back(i);
}
static bool compileLispFragment(char const*& d, char const* e, bool _quiet, u256s& o_code, vector<unsigned>& o_locs)
{
std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD } };
std::map<std::string, Instruction> const c_binary = { { "<", Instruction::LT }, { "<=", Instruction::LE }, { ">", Instruction::GT }, { ">=", Instruction::GE }, { "=", Instruction::EQ }, { "!=", Instruction::NOT } };
std::map<std::string, Instruction> const c_unary = { { "!", Instruction::NOT } };
std::set<char> const c_allowed = { '+', '-', '*', '/', '%', '<', '>', '=', '!' };
bool exec = false;
while (d != e)
{
// skip to next token
for (; d != e && !isalnum(*d) && *d != '(' && *d != ')' && *d != '_' && *d != '"' && !c_allowed.count(*d) && *d != ';'; ++d) {}
if (d == e)
break;
switch (*d)
{
case ';':
for (; d != e && *d != '\n'; ++d) {}
break;
case '(':
exec = true;
++d;
break;
case ')':
if (exec)
{
++d;
return true;
}
else
// unexpected - return false as we don't know what to do with it.
return false;
default:
{
bool haveLiteral = false;
u256 literalValue = 0;
string t;
if (*d == '"')
{
string s = readQuoted(d, e);
if (s.size() > 32)
{
if (!_quiet)
cwarn << "String literal > 32 characters. Cropping.";
s.resize(32);
}
h256 valHash;
memcpy(valHash.data(), s.data(), s.size());
memset(valHash.data() + s.size(), 0, 32 - s.size());
literalValue = (u256)valHash;
haveLiteral = true;
}
else
{
char const* s = d;
for (; d != e && (isalnum(*d) || *d == '_' || c_allowed.count(*d)); ++d) {}
t = string(s, d - s);
if (isdigit(t[0]))
{
literalValue = readNumeric(t, _quiet);
haveLiteral = true;
}
}
if (haveLiteral)
{
bool bareLoad = true;
if (exec)
{
u256s codes;
vector<unsigned> locs;
if (compileLispFragment(d, e, _quiet, codes, locs))
{
appendCode(o_code, o_locs, codes, locs);
while (compileLispFragment(d, e, _quiet, codes, locs))
if (!_quiet)
cwarn << "Additional items in bare store. Ignoring.";
bareLoad = false;
}
}
o_code.push_back(Instruction::PUSH);
o_code.push_back(literalValue);
if (exec)
o_code.push_back(bareLoad ? Instruction::SLOAD : Instruction::SSTORE);
}
else
{
boost::algorithm::to_upper(t);
if (t == "IF")
{
// Compile all the code...
u256s codes[4];
vector<unsigned> locs[4];
for (int i = 0; i < 3; ++i)
if (!compileLispFragment(d, e, _quiet, codes[i], locs[i]))
return false;
if (compileLispFragment(d, e, _quiet, codes[3], locs[3]))
return false;
// Push the positive location.
o_code.push_back(Instruction::PUSH);
unsigned posLocation = (unsigned)o_code.size();
o_locs.push_back(posLocation);
o_code.push_back(0);
// First fragment - predicate
appendCode(o_code, o_locs, codes[0], locs[0]);
// Jump to positive if true.
o_code.push_back(Instruction::JMPI);
// Second fragment - negative.
appendCode(o_code, o_locs, codes[2], locs[2]);
// Jump to end after negative.
o_code.push_back(Instruction::PUSH);
unsigned endLocation = (unsigned)o_code.size();
o_locs.push_back(endLocation);
o_code.push_back(0);
o_code.push_back(Instruction::JMP);
// Third fragment - positive.
o_code[posLocation] = o_code.size();
appendCode(o_code, o_locs, codes[1], locs[1]);
// At end now.
o_code[endLocation] = o_code.size();
}
else if (t == "WHEN" || t == "UNLESS")
{
// Compile all the code...
u256s codes[3];
vector<unsigned> locs[3];
for (int i = 0; i < 2; ++i)
if (!compileLispFragment(d, e, _quiet, codes[i], locs[i]))
return false;
if (compileLispFragment(d, e, _quiet, codes[2], locs[2]))
return false;
// Push the positive location.
o_code.push_back(Instruction::PUSH);
unsigned endLocation = (unsigned)o_code.size();
o_locs.push_back(endLocation);
o_code.push_back(0);
// First fragment - predicate
appendCode(o_code, o_locs, codes[0], locs[0]);
// Jump to end...
if (t == "WHEN")
o_code.push_back(Instruction::NOT);
o_code.push_back(Instruction::JMPI);
// Second fragment - negative.
appendCode(o_code, o_locs, codes[1], locs[1]);
// At end now.
o_code[endLocation] = o_code.size();
}
else if (t == "FOR")
{
// Compile all the code...
u256s codes[3];
vector<unsigned> locs[3];
for (int i = 0; i < 2; ++i)
if (!compileLispFragment(d, e, _quiet, codes[i], locs[i]))
return false;
if (compileLispFragment(d, e, _quiet, codes[2], locs[2]))
return false;
unsigned startLocation = (unsigned)o_code.size();
// Push the positive location.
o_code.push_back(Instruction::PUSH);
unsigned endInsertion = (unsigned)o_code.size();
o_locs.push_back(endInsertion);
o_code.push_back(0);
// First fragment - predicate
appendCode(o_code, o_locs, codes[0], locs[0]);
// Jump to positive if true.
o_code.push_back(Instruction::NOT);
o_code.push_back(Instruction::JMPI);
// Second fragment - negative.
appendCode(o_code, o_locs, codes[1], locs[1]);
// Jump to end after negative.
o_code.push_back(Instruction::PUSH);
o_locs.push_back((unsigned)o_code.size());
o_code.push_back(startLocation);
o_code.push_back(Instruction::JMP);
// At end now.
o_code[endInsertion] = o_code.size();
}
else if (t == "SEQ")
{
while (d != e)
{
u256s codes;
vector<unsigned> locs;
if (compileLispFragment(d, e, _quiet, codes, locs))
appendCode(o_code, o_locs, codes, locs);
else
break;
}
}
else if (t == "AND")
{
vector<u256s> codes;
vector<vector<unsigned>> locs;
while (d != e)
{
codes.resize(codes.size() + 1);
locs.resize(locs.size() + 1);
if (!compileLispFragment(d, e, _quiet, codes.back(), locs.back()))
break;
}
// last one is empty.
if (codes.size() < 2)
return false;
codes.pop_back();
locs.pop_back();
vector<unsigned> ends;
if (codes.size() > 1)
{
o_code.push_back(Instruction::PUSH);
o_code.push_back(0);
for (unsigned i = 1; i < codes.size(); ++i)
{
// Push the false location.
o_code.push_back(Instruction::PUSH);
ends.push_back((unsigned)o_code.size());
o_locs.push_back(ends.back());
o_code.push_back(0);
// Check if true - predicate
appendCode(o_code, o_locs, codes[i - 1], locs[i - 1]);
// Jump to end...
o_code.push_back(Instruction::NOT);
o_code.push_back(Instruction::JMPI);
}
o_code.push_back(Instruction::POP);
}
// Check if true - predicate
appendCode(o_code, o_locs, codes.back(), locs.back());
// At end now.
for (auto i: ends)
o_code[i] = o_code.size();
}
else if (t == "OR")
{
vector<u256s> codes;
vector<vector<unsigned>> locs;
while (d != e)
{
codes.resize(codes.size() + 1);
locs.resize(locs.size() + 1);
if (!compileLispFragment(d, e, _quiet, codes.back(), locs.back()))
break;
}
// last one is empty.
if (codes.size() < 2)
return false;
codes.pop_back();
locs.pop_back();
vector<unsigned> ends;
if (codes.size() > 1)
{
o_code.push_back(Instruction::PUSH);
o_code.push_back(1);
for (unsigned i = 1; i < codes.size(); ++i)
{
// Push the false location.
o_code.push_back(Instruction::PUSH);
ends.push_back((unsigned)o_code.size());
o_locs.push_back(ends.back());
o_code.push_back(0);
// Check if true - predicate
appendCode(o_code, o_locs, codes[i - 1], locs[i - 1]);
// Jump to end...
o_code.push_back(Instruction::JMPI);
}
o_code.push_back(Instruction::POP);
}
// Check if true - predicate
appendCode(o_code, o_locs, codes.back(), locs.back());
// At end now.
for (auto i: ends)
o_code[i] = o_code.size();
}
else
{
auto it = c_instructions.find(t);
if (it != c_instructions.end())
{
if (exec)
{
vector<pair<u256s, vector<unsigned>>> codes(1);
while (d != e && compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second))
codes.push_back(pair<u256s, vector<unsigned>>());
for (auto it = codes.rbegin(); it != codes.rend(); ++it)
appendCode(o_code, o_locs, it->first, it->second);
o_code.push_back((u256)it->second);
}
else
{
o_code.push_back(Instruction::PUSH);
o_code.push_back(it->second);
}
}
else
{
auto it = c_arith.find(t);
if (it != c_arith.end())
{
int i = 0;
while (d != e)
{
u256s codes;
vector<unsigned> locs;
if (compileLispFragment(d, e, _quiet, codes, locs))
{
appendCode(o_code, o_locs, codes, locs);
if (i)
o_code.push_back((u256)it->second);
++i;
}
else
break;
}
}
else
{
auto it = c_binary.find(t);
if (it != c_binary.end())
{
vector<pair<u256s, vector<unsigned>>> codes(1);
while (d != e && compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second))
codes.push_back(pair<u256s, vector<unsigned>>());
codes.pop_back();
int i = (int)codes.size();
if (i > 2)
cwarn << "Greater than two arguments given to binary operator" << t << "; using first two only.";
for (auto it = codes.rbegin(); it != codes.rend(); ++it)
if (--i < 2)
appendCode(o_code, o_locs, it->first, it->second);
if (it->second == Instruction::NOT)
o_code.push_back(Instruction::EQ);
o_code.push_back((u256)it->second);
}
else
{
auto it = c_unary.find(t);
if (it != c_unary.end())
{
vector<pair<u256s, vector<unsigned>>> codes(1);
while (d != e && compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second))
codes.push_back(pair<u256s, vector<unsigned>>());
codes.pop_back();
int i = (int)codes.size();
if (i > 1)
cwarn << "Greater than one argument given to unary operator" << t << "; using first only.";
for (auto it = codes.rbegin(); it != codes.rend(); ++it)
if (--i < 1)
appendCode(o_code, o_locs, it->first, it->second);
o_code.push_back(it->second);
}
else if (!_quiet)
cwarn << "Unknown assembler token" << t;
}
}
}
}
}
if (!exec)
return true;
}
}
}
return false;
}
u256s eth::compileLisp(std::string const& _code, bool _quiet)
{
char const* d = _code.data();
char const* e = _code.data() + _code.size();
u256s ret;
vector<unsigned> locs;
compileLispFragment(d, e, _quiet, ret, locs);
return ret;
}
string eth::disassemble(u256s const& _mem)
{
stringstream ret;
uint numerics = 0;
for (auto it = _mem.begin(); it != _mem.end(); ++it)
{
u256 n = *it;
auto iit = c_instructionInfo.find((Instruction)(uint)n);
if (numerics || iit == c_instructionInfo.end() || (u256)(uint)iit->first != n) // not an instruction or expecting an argument...
{
if (numerics)
numerics--;
ret << "0x" << hex << n << " ";
}
else
{
auto const& ii = iit->second;
ret << ii.name << " ";
numerics = ii.additional;
}
}
return ret.str();
}

168
libethereum/Instruction.h

@ -1,5 +1,28 @@
/*
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 Instruction.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include "Common.h"
namespace eth
{
@ -10,8 +33,8 @@ enum class Instruction: uint8_t
{
STOP = 0x00, ///< halts execution
ADD,
SUB,
MUL,
SUB,
DIV,
SDIV,
MOD,
@ -24,10 +47,9 @@ enum class Instruction: uint8_t
GE,
EQ,
NOT,
MYADDRESS = 0x10,
MYADDRESS, ///< pushes the transaction sender
TXSENDER, ///< pushes the transaction sender
TXVALUE , ///< pushes the transaction value
TXFEE, ///< pushes the transaction fee
TXDATAN, ///< pushes the number of data items
TXDATA, ///< pops one item and pushes data item S[-1], or zero if index out of range
BLK_PREVHASH, ///< pushes the hash of the previous block (NOT the current one since that's impossible!)
@ -35,6 +57,8 @@ enum class Instruction: uint8_t
BLK_TIMESTAMP, ///< pushes the timestamp of the current block
BLK_NUMBER, ///< pushes the current block number
BLK_DIFFICULTY, ///< pushes the difficulty of the current block
BLK_NONCE,
BASEFEE,
SHA256 = 0x20,
RIPEMD160,
ECMUL,
@ -46,18 +70,140 @@ enum class Instruction: uint8_t
PUSH = 0x30,
POP,
DUP,
DUPN,
SWAP,
SWAPN,
LOAD,
STORE,
JMP = 0x40,
MLOAD,
MSTORE,
SLOAD,
SSTORE,
JMP,
JMPI,
IND,
EXTRO = 0x50,
EXTRO,
BALANCE,
MKTX = 0x60,
SUICIDE = 0xff
MKTX,
SUICIDE = 0x3f
};
struct InstructionInfo
{
std::string name;
int additional;
int args;
int ret;
};
static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{
{ Instruction::STOP, { "STOP", 0, 0, 0 } },
{ Instruction::ADD, { "ADD", 0, 2, 1 } },
{ Instruction::SUB, { "SUB", 0, 2, 1 } },
{ Instruction::MUL, { "MUL", 0, 2, 1 } },
{ Instruction::DIV, { "DIV", 0, 2, 1 } },
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } },
{ Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NEG, { "NEG", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::LE, { "LE", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::GE, { "GE", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::NOT, { "NOT", 0, 1, 1 } },
{ Instruction::MYADDRESS, { "MYADDRESS", 0, 0, 1 } },
{ Instruction::TXSENDER, { "TXSENDER", 0, 0, 1 } },
{ Instruction::TXVALUE, { "TXVALUE", 0, 0, 1 } },
{ Instruction::TXDATAN, { "TXDATAN", 0, 0, 1 } },
{ Instruction::TXDATA, { "TXDATA", 0, 1, 1 } },
{ Instruction::BLK_PREVHASH, { "BLK_PREVHASH", 0, 0, 1 } },
{ Instruction::BLK_COINBASE, { "BLK_COINBASE", 0, 0, 1 } },
{ Instruction::BLK_TIMESTAMP, { "BLK_TIMESTAMP", 0, 0, 1 } },
{ Instruction::BLK_NUMBER, { "BLK_NUMBER", 0, 0, 1 } },
{ Instruction::BLK_DIFFICULTY, { "BLK_DIFFICULTY", 0, 0, 1 } },
{ Instruction::BLK_NONCE, { "BLK_NONCE", 0, 0, 1 } },
{ Instruction::BASEFEE, { "BASEFEE", 0, 0, 1 } },
{ Instruction::SHA256, { "SHA256", 0, -1, 1 } },
{ Instruction::RIPEMD160, { "RIPEMD160", 0, -1, 1 } },
{ Instruction::ECMUL, { "ECMUL", 0, 3, 1 } },
{ Instruction::ECADD, { "ECADD", 0, 4, 1 } },
{ Instruction::ECSIGN, { "ECSIGN", 0, 2, 1 } },
{ Instruction::ECRECOVER, { "ECRECOVER", 0, 4, 1 } },
{ Instruction::ECVALID, { "ECVALID", 0, 2, 1 } },
{ Instruction::SHA3, { "SHA3", 0, -1, 1 } },
{ Instruction::PUSH, { "PUSH", 1, 0, 1 } },
{ Instruction::POP, { "POP", 0, 1, 0 } },
{ Instruction::DUP, { "DUP", 0, 1, 2 } },
{ Instruction::SWAP, { "SWAP", 0, 2, 2 } },
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } },
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } },
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } },
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } },
{ Instruction::JMP, { "JMP", 0, 1, 0 } },
{ Instruction::JMPI, { "JMPI", 0, 2, 0 } },
{ Instruction::IND, { "IND", 0, 0, 1 } },
{ Instruction::EXTRO, { "EXTRO", 0, 2, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },
{ Instruction::MKTX, { "MKTX", 0, -3, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }
};
static const std::map<std::string, Instruction> c_instructions =
{
{ "STOP", Instruction::STOP },
{ "ADD", Instruction::ADD },
{ "SUB", Instruction::SUB },
{ "MUL", Instruction::MUL },
{ "DIV", Instruction::DIV },
{ "SDIV", Instruction::SDIV },
{ "MOD", Instruction::MOD },
{ "SMOD", Instruction::SMOD },
{ "EXP", Instruction::EXP },
{ "NEG", Instruction::NEG },
{ "LT", Instruction::LT },
{ "LE", Instruction::LE },
{ "GT", Instruction::GT },
{ "GE", Instruction::GE },
{ "EQ", Instruction::EQ },
{ "NOT", Instruction::NOT },
{ "MYADDRESS", Instruction::MYADDRESS },
{ "TXSENDER", Instruction::TXSENDER },
{ "TXVALUE", Instruction::TXVALUE },
{ "TXDATAN", Instruction::TXDATAN },
{ "TXDATA", Instruction::TXDATA },
{ "BLK_PREVHASH", Instruction::BLK_PREVHASH },
{ "BLK_COINBASE", Instruction::BLK_COINBASE },
{ "BLK_TIMESTAMP", Instruction::BLK_TIMESTAMP },
{ "BLK_NUMBER", Instruction::BLK_NUMBER },
{ "BLK_DIFFICULTY", Instruction::BLK_DIFFICULTY },
{ "BLK_NONCE", Instruction::BLK_NONCE },
{ "BASEFEE", Instruction::BASEFEE },
{ "SHA256", Instruction::SHA256 },
{ "RIPEMD160", Instruction::RIPEMD160 },
{ "ECMUL", Instruction::ECMUL },
{ "ECADD", Instruction::ECADD },
{ "ECSIGN", Instruction::ECSIGN },
{ "ECRECOVER", Instruction::ECRECOVER },
{ "ECVALID", Instruction::ECVALID },
{ "SHA3", Instruction::SHA3 },
{ "PUSH", Instruction::PUSH },
{ "POP", Instruction::POP },
{ "DUP", Instruction::DUP },
{ "SWAP", Instruction::SWAP },
{ "MLOAD", Instruction::MLOAD },
{ "MSTORE", Instruction::MSTORE },
{ "SLOAD", Instruction::SLOAD },
{ "SSTORE", Instruction::SSTORE },
{ "JMP", Instruction::JMP },
{ "JMPI", Instruction::JMPI },
{ "IND", Instruction::IND },
{ "EXTRO", Instruction::EXTRO },
{ "BALANCE", Instruction::BALANCE },
{ "MKTX", Instruction::MKTX },
{ "SUICIDE", Instruction::SUICIDE }
};
u256s assemble(std::string const& _code, bool _quiet = false);
std::string disassemble(u256s const& _mem);
u256s compileLisp(std::string const& _code, bool _quiet = false);
}

19
libethereum/LibEthereum.props

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<IncludePath>$(IncludePath);../../boost_1_55_0;../../leveldb-1.15.0/include;../../cryptopp562;../../secp256k1/include</IncludePath>
<OutDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<IntDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<DisableSpecificWarnings>4100;4127;4505;4512;</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

32
libethereum/LibEthereum.vcxproj.filters

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="TransactionQueue.h" />
<ClInclude Include="Trie.h" />
<ClInclude Include="vector_ref.h" />
<ClInclude Include="AddressState.h" />
<ClInclude Include="BlockChain.h" />
<ClInclude Include="BlockInfo.h" />
<ClInclude Include="Common.h" />
<ClInclude Include="Dagger.h" />
<ClInclude Include="Exceptions.h" />
<ClInclude Include="Instruction.h" />
<ClInclude Include="PeerNetwork.h" />
<ClInclude Include="RLP.h" />
<ClInclude Include="State.h" />
<ClInclude Include="Transaction.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Trie.cpp" />
<ClCompile Include="AddressState.cpp" />
<ClCompile Include="BlockChain.cpp" />
<ClCompile Include="BlockInfo.cpp" />
<ClCompile Include="Common.cpp" />
<ClCompile Include="Dagger.cpp" />
<ClCompile Include="PeerNetwork.cpp" />
<ClCompile Include="RLP.cpp" />
<ClCompile Include="State.cpp" />
<ClCompile Include="Transaction.cpp" />
<ClCompile Include="TransactionQueue.cpp" />
</ItemGroup>
</Project>

63
libethereum/PeerNetwork.cpp

@ -43,7 +43,7 @@ using namespace eth;
#define clogS(X) eth::LogOutputStream<X, true>(false) << "| " << std::setw(2) << m_socket.native_handle() << "] "
static const int c_protocolVersion = 4;
static const int c_protocolVersion = 7;
static const eth::uint c_maxHashes = 32; ///< Maximum number of hashes GetChain will ever send.
static const eth::uint c_maxBlocks = 32; ///< Maximum number of blocks Blocks will ever send. BUG: if this gets too big (e.g. 2048) stuff starts going wrong.
@ -80,7 +80,7 @@ bool eth::isPrivateAddress(bi::address _addressToCheck)
return false;
}
PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, short _peerPort):
PeerSession::PeerSession(PeerServer* _s, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, unsigned short _peerPort):
m_server(_s),
m_socket(std::move(_socket)),
m_reqNetworkId(_rNId),
@ -137,7 +137,7 @@ bool PeerSession::interpret(RLP const& _r)
m_networkId = _r[2].toInt<uint>();
auto clientVersion = _r[3].toString();
m_caps = _r[4].toInt<uint>();
m_listenPort = _r[5].toInt<short>();
m_listenPort = _r[5].toInt<unsigned short>();
m_id = _r[6].toHash<h512>();
clogS(NetMessageSummary) << "Hello: " << clientVersion << "V[" << m_protocolVersion << "/" << m_networkId << "]" << m_id.abridged() << showbase << hex << m_caps << dec << m_listenPort;
@ -170,12 +170,12 @@ bool PeerSession::interpret(RLP const& _r)
// Grab their block chain off them.
{
clogS(NetAllDetail) << "Want chain. Latest:" << m_server->m_latestBlockSent << ", number:" << m_server->m_chain->details(m_server->m_latestBlockSent).number;
unsigned count = std::min<unsigned>(c_maxHashes, m_server->m_chain->details(m_server->m_latestBlockSent).number + 1);
uint count = std::min(c_maxHashes, m_server->m_chain->details(m_server->m_latestBlockSent).number + 1);
RLPStream s;
prep(s).appendList(2 + count);
s << GetChainPacket;
auto h = m_server->m_latestBlockSent;
for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent)
for (uint i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent)
{
clogS(NetAllDetail) << " " << i << ":" << h;
s << h;
@ -407,12 +407,12 @@ bool PeerSession::interpret(RLP const& _r)
}
else
{
unsigned count = std::min<unsigned>(c_maxHashes, m_server->m_chain->details(noGood).number);
uint count = std::min(c_maxHashes, m_server->m_chain->details(noGood).number);
RLPStream s;
prep(s).appendList(2 + count);
s << GetChainPacket;
auto h = m_server->m_chain->details(noGood).parent;
for (unsigned i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent)
for (uint i = 0; i < count; ++i, h = m_server->m_chain->details(h).parent)
s << h;
s << c_maxBlocksAsk;
sealAndSend(s);
@ -450,7 +450,7 @@ void PeerServer::seal(bytes& _b)
_b[1] = 0x40;
_b[2] = 0x08;
_b[3] = 0x91;
uint32_t len = _b.size() - 8;
uint32_t len = (uint32_t)_b.size() - 8;
_b[4] = (len >> 24) & 0xff;
_b[5] = (len >> 16) & 0xff;
_b[6] = (len >> 8) & 0xff;
@ -483,19 +483,21 @@ bool PeerSession::checkPacket(bytesConstRef _msg)
void PeerSession::sendDestroy(bytes& _msg)
{
clogS(NetLeft) << RLP(bytesConstRef(&_msg).cropped(8));
std::shared_ptr<bytes> buffer = std::make_shared<bytes>();
swap(*buffer, _msg);
if (!checkPacket(bytesConstRef(&*buffer)))
if (!checkPacket(bytesConstRef(&_msg)))
{
cwarn << "INVALID PACKET CONSTRUCTED!";
}
ba::async_write(m_socket, ba::buffer(*buffer), [=](boost::system::error_code ec, std::size_t length)
auto self(shared_from_this());
bytes* buffer = new bytes(std::move(_msg));
ba::async_write(m_socket, ba::buffer(*buffer), [self,buffer](boost::system::error_code ec, std::size_t length)
{
delete buffer;
if (ec)
{
cwarn << "Error sending: " << ec.message();
dropped();
self->dropped();
}
// cbug << length << " bytes written (EC: " << ec << ")";
});
@ -504,17 +506,21 @@ void PeerSession::sendDestroy(bytes& _msg)
void PeerSession::send(bytesConstRef _msg)
{
clogS(NetLeft) << RLP(_msg.cropped(8));
std::shared_ptr<bytes> buffer = std::make_shared<bytes>(_msg.toBytes());
if (!checkPacket(_msg))
{
cwarn << "INVALID PACKET CONSTRUCTED!";
}
ba::async_write(m_socket, ba::buffer(*buffer), [=](boost::system::error_code ec, std::size_t length)
auto self(shared_from_this());
bytes* buffer = new bytes(_msg.toBytes());
ba::async_write(m_socket, ba::buffer(*buffer), [self,buffer](boost::system::error_code ec, std::size_t length)
{
delete buffer;
if (ec)
{
cwarn << "Error sending: " << ec.message();
dropped();
self->dropped();
}
// cbug << length << " bytes written (EC: " << ec << ")";
});
@ -568,7 +574,7 @@ void PeerSession::start()
void PeerSession::doRead()
{
auto self(shared_from_this());
m_socket.async_read_some(boost::asio::buffer(m_data), [this, self](boost::system::error_code ec, std::size_t length)
m_socket.async_read_some(boost::asio::buffer(m_data), [this,self](boost::system::error_code ec, std::size_t length)
{
if (ec)
{
@ -635,7 +641,7 @@ void PeerSession::doRead()
});
}
PeerServer::PeerServer(std::string const& _clientVersion, BlockChain const& _ch, uint _networkId, short _port, NodeMode _m, string const& _publicAddress, bool _upnp):
PeerServer::PeerServer(std::string const& _clientVersion, BlockChain const& _ch, uint _networkId, unsigned short _port, NodeMode _m, string const& _publicAddress, bool _upnp):
m_clientVersion(_clientVersion),
m_mode(_m),
m_listenPort(_port),
@ -654,7 +660,7 @@ PeerServer::PeerServer(std::string const& _clientVersion, BlockChain const& _ch,
PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId, NodeMode _m):
m_clientVersion(_clientVersion),
m_mode(_m),
m_listenPort(-1),
m_listenPort(0),
m_acceptor(m_ioService, bi::tcp::endpoint(bi::tcp::v4(), 0)),
m_socket(m_ioService),
m_key(KeyPair::create()),
@ -698,10 +704,10 @@ void PeerServer::determinePublic(string const& _publicAddress, bool _upnp)
auto eip = m_upnp->externalIP();
if (eip == string("0.0.0.0") && _publicAddress.empty())
m_public = bi::tcp::endpoint(bi::address(), p);
m_public = bi::tcp::endpoint(bi::address(), (unsigned short)p);
else
{
m_public = bi::tcp::endpoint(bi::address::from_string(_publicAddress.empty() ? eip : _publicAddress), p);
m_public = bi::tcp::endpoint(bi::address::from_string(_publicAddress.empty() ? eip : _publicAddress), (unsigned short)p);
m_addresses.push_back(m_public.address().to_v4());
}
}
@ -746,7 +752,7 @@ void PeerServer::populateAddresses()
bi::address ad(bi::address::from_string(addrStr));
m_addresses.push_back(ad.to_v4());
bool isLocal = std::find(c_rejectAddresses.begin(), c_rejectAddresses.end(), ad) != c_rejectAddresses.end();
if (isLocal)
if (!isLocal)
m_peerAddresses.push_back(ad.to_v4());
clog(NetNote) << "Address: " << ac << " = " << m_addresses.back() << (isLocal ? " [LOCAL]" : " [PEER]");
}
@ -768,6 +774,7 @@ void PeerServer::populateAddresses()
char host[NI_MAXHOST];
if (getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST))
continue;
// TODO: Make exception safe when no internet.
auto it = r.resolve({host, "30303"});
bi::tcp::endpoint ep = it->endpoint();
bi::address ad = ep.address();
@ -831,7 +838,7 @@ void PeerServer::ensureAccepting()
}
}
void PeerServer::connect(std::string const& _addr, uint _port) noexcept
void PeerServer::connect(std::string const& _addr, unsigned short _port) noexcept
{
try
{
@ -866,7 +873,7 @@ void PeerServer::connect(bi::tcp::endpoint const& _ep)
else
{
auto p = make_shared<PeerSession>(this, std::move(*s), m_requiredNetworkId, _ep.address(), _ep.port());
clog(NetNote) << "Connected to " << p->endpoint();
clog(NetNote) << "Connected to " << _ep;
p->start();
}
delete s;
@ -924,6 +931,9 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.
m_incomingTransactions.clear();
auto h = _bc.currentHash();
bool resendAll = (h != m_latestBlockSent);
// Send any new transactions.
for (auto j: m_peers)
if (auto p = j.second.lock())
@ -931,7 +941,7 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
bytes b;
uint n = 0;
for (auto const& i: _tq.transactions())
if ((!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first)) || p->m_requireTransactions)
if ((!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first)) || p->m_requireTransactions || resendAll)
{
b += i.second;
++n;
@ -951,7 +961,6 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
}
// Send any new blocks.
auto h = _bc.currentHash();
if (h != m_latestBlockSent)
{
// TODO: find where they diverge and send complete new branch.

34
libethereum/PeerNetwork.h

@ -40,13 +40,13 @@ bool isPrivateAddress(bi::address _addressToCheck);
class BlockChain;
class TransactionQueue;
struct NetWarn: public LogChannel { static const char constexpr* name = "!N!"; static const int verbosity = 0; };
struct NetNote: public LogChannel { static const char constexpr* name = "*N*"; static const int verbosity = 1; };
struct NetMessageSummary: public LogChannel { static const char constexpr* name = "-N-"; static const int verbosity = 2; };
struct NetMessageDetail: public LogChannel { static const char constexpr* name = "=N="; static const int verbosity = 3; };
struct NetAllDetail: public LogChannel { static const char constexpr* name = "=N="; static const int verbosity = 6; };
struct NetRight: public LogChannel { static const char constexpr* name = ">N>"; static const int verbosity = 8; };
struct NetLeft: public LogChannel { static const char constexpr* name = "<N<"; static const int verbosity = 9; };
struct NetWarn: public LogChannel { static const char* name() { return "!N!"; } static const int verbosity = 0; };
struct NetNote: public LogChannel { static const char* name() { return "*N*"; } static const int verbosity = 1; };
struct NetMessageSummary: public LogChannel { static const char* name() { return "-N-"; } static const int verbosity = 2; };
struct NetMessageDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 3; };
struct NetAllDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 6; };
struct NetRight: public LogChannel { static const char* name() { return ">N>"; } static const int verbosity = 8; };
struct NetLeft: public LogChannel { static const char* name() { return "<N<"; } static const int verbosity = 9; };
enum PacketType
{
@ -82,7 +82,7 @@ struct PeerInfo
{
std::string clientVersion;
std::string host;
short port;
unsigned short port;
std::chrono::steady_clock::duration lastPing;
};
@ -91,7 +91,7 @@ class PeerSession: public std::enable_shared_from_this<PeerSession>
friend class PeerServer;
public:
PeerSession(PeerServer* _server, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, short _peerPort = 0);
PeerSession(PeerServer* _server, bi::tcp::socket _socket, uint _rNId, bi::address _peerAddress, unsigned short _peerPort = 0);
~PeerSession();
void start();
@ -127,14 +127,14 @@ private:
uint m_protocolVersion;
uint m_networkId;
uint m_reqNetworkId;
short m_listenPort; ///< Port that the remote client is listening on for connections. Useful for giving to peers.
unsigned short m_listenPort; ///< Port that the remote client is listening on for connections. Useful for giving to peers.
uint m_caps;
std::chrono::steady_clock::time_point m_ping;
std::chrono::steady_clock::time_point m_connect;
std::chrono::steady_clock::time_point m_disconnect;
unsigned m_rating;
uint m_rating;
bool m_requireTransactions;
std::set<h256> m_knownBlocks;
@ -147,7 +147,7 @@ enum class NodeMode
PeerServer
};
struct UPnP;
class UPnP;
class PeerServer
{
@ -155,13 +155,13 @@ class PeerServer
public:
/// Start server, listening for connections on the given port.
PeerServer(std::string const& _clientVersion, BlockChain const& _ch, uint _networkId, short _port, NodeMode _m = NodeMode::Full, std::string const& _publicAddress = std::string(), bool _upnp = true);
PeerServer(std::string const& _clientVersion, BlockChain const& _ch, uint _networkId, unsigned short _port, NodeMode _m = NodeMode::Full, std::string const& _publicAddress = std::string(), bool _upnp = true);
/// Start server, but don't listen.
PeerServer(std::string const& _clientVersion, uint _networkId, NodeMode _m = NodeMode::Full);
~PeerServer();
/// Connect to a peer explicitly.
void connect(std::string const& _addr, uint _port = 30303) noexcept;
void connect(std::string const& _addr, unsigned short _port = 30303) noexcept;
void connect(bi::tcp::endpoint const& _ep);
/// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network.
@ -182,13 +182,13 @@ public:
std::vector<PeerInfo> peers() const;
/// Get number of peers connected; equivalent to, but faster than, peers().size().
unsigned peerCount() const { return m_peers.size(); }
size_t peerCount() const { return m_peers.size(); }
/// Ping the peers, to update the latency information.
void pingAll();
/// Get the port we're listening on currently.
short listenPort() const { return m_public.port(); }
unsigned short listenPort() const { return m_public.port(); }
bytes savePeers() const;
void restorePeers(bytesConstRef _b);
@ -209,7 +209,7 @@ private:
std::string m_clientVersion;
NodeMode m_mode = NodeMode::Full;
short m_listenPort;
unsigned short m_listenPort;
BlockChain const* m_chain = nullptr;
ba::io_service m_ioService;

26
libethereum/RLP.cpp

@ -102,9 +102,17 @@ bool RLP::isInt() const
else if (n == c_rlpDataImmLenStart)
return true;
else if (n <= c_rlpDataIndLenZero)
return m_data[1];
{
if (m_data.size() <= 1)
throw BadRLP();
return m_data[1] != 0;
}
else if (n < c_rlpListStart)
return m_data[1 + n - c_rlpDataIndLenZero];
{
if ((int)m_data.size() <= 1 + n - c_rlpDataIndLenZero)
throw BadRLP();
return m_data[1 + n - c_rlpDataIndLenZero] != 0;
}
else
return false;
return false;
@ -121,13 +129,21 @@ eth::uint RLP::length() const
else if (n <= c_rlpDataIndLenZero)
return n - c_rlpDataImmLenStart;
else if (n < c_rlpListStart)
{
if ((int)m_data.size() <= n - c_rlpDataIndLenZero)
throw BadRLP();
for (int i = 0; i < n - c_rlpDataIndLenZero; ++i)
ret = (ret << 8) | m_data[i + 1];
}
else if (n <= c_rlpListIndLenZero)
return n - c_rlpListStart;
else
{
if ((int)m_data.size() <= n - c_rlpListIndLenZero)
throw BadRLP();
for (int i = 0; i < n - c_rlpListIndLenZero; ++i)
ret = (ret << 8) | m_data[i + 1];
}
return ret;
}
@ -176,10 +192,10 @@ void RLPStream::noteAppended(uint _itemCount)
m_out.resize(os + encodeSize);
memmove(m_out.data() + p + encodeSize, m_out.data() + p, os - p);
if (s < c_rlpListImmLenCount)
m_out[p] = c_rlpListStart + s;
m_out[p] = (byte)(c_rlpListStart + s);
else
{
m_out[p] = c_rlpListIndLenZero + brs;
m_out[p] = (byte)(c_rlpListIndLenZero + brs);
byte* b = &(m_out[p + brs]);
for (; s; s >>= 8)
*(b--) = (byte)s;
@ -189,7 +205,7 @@ void RLPStream::noteAppended(uint _itemCount)
}
}
RLPStream& RLPStream::appendList(unsigned _items)
RLPStream& RLPStream::appendList(uint _items)
{
// cdebug << "appendList(" << _items << ")";
if (_items)

7
libethereum/RLP.h

@ -30,6 +30,7 @@
#include <iomanip>
#include "vector_ref.h"
#include "Common.h"
#include "Exceptions.h"
namespace eth
{
@ -60,8 +61,6 @@ static const byte c_rlpListIndLenZero = c_rlpListStart + c_rlpListImmLenCount -
class RLP
{
public:
class BadCast: public std::exception {};
/// Construct a null node.
RLP() {}
@ -175,7 +174,7 @@ public:
std::string toStringStrict() const { if (!isData()) throw BadCast(); return payload().cropped(0, length()).toString(); }
template <class T> std::vector<T> toVector() const { std::vector<T> ret; if (isList()) { ret.reserve(itemCount()); for (auto const& i: *this) ret.push_back((T)i); } return ret; }
template <class T, size_t N> std::array<T, N> toArray() const { std::array<T, N> ret; if (itemCount() != N) throw BadCast(); if (isList()) for (uint i = 0; i < N; ++i) ret[i] = (T)operator[](i); return ret; }
template <class T, size_t N> std::array<T, N> toArray() const { if (itemCount() != N || !isList()) throw BadCast(); std::array<T, N> ret; for (uint i = 0; i < N; ++i) ret[i] = (T)operator[](i); return ret; }
/// Int conversion flags
enum
@ -288,7 +287,7 @@ public:
template <class _T, size_t S> RLPStream& append(std::array<_T, S> const& _s) { appendList(_s.size()); for (auto const& i: _s) append(i); return *this; }
/// Appends a list.
RLPStream& appendList(unsigned _items);
RLPStream& appendList(uint _items);
RLPStream& appendList(bytesConstRef _rlp);
RLPStream& appendList(bytes const& _rlp) { return appendList(&_rlp); }
RLPStream& appendList(RLPStream const& _s) { return appendList(&_s.out()); }

722
libethereum/State.cpp

@ -23,19 +23,6 @@
#include <secp256k1.h>
#include <boost/filesystem.hpp>
#if WIN32
#pragma warning(push)
#pragma warning(disable:4244)
#else
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
#include <sha.h>
#include <sha3.h>
#include <ripemd.h>
#if WIN32
#pragma warning(pop)
#else
#endif
#include <time.h>
#include <random>
#include "BlockChain.h"
@ -43,18 +30,11 @@
#include "Exceptions.h"
#include "Dagger.h"
#include "Defaults.h"
#include "VM.h"
using namespace std;
using namespace eth;
u256 const c_stepFee = 1;
u256 const c_dataFee = 20;
u256 const c_memoryFee = 5;
u256 const c_extroFee = 40;
u256 const c_cryptoFee = 20;
u256 const c_newContractFee = 100;
u256 const c_txFee = 100;
u256 const eth::c_genesisDifficulty = (u256)1 << 22;
u256 eth::c_genesisDifficulty = (u256)1 << 22;
std::map<Address, AddressState> const& eth::genesisState()
{
@ -62,10 +42,10 @@ std::map<Address, AddressState> const& eth::genesisState()
if (s_ret.empty())
{
// Initialise.
s_ret[Address(fromUserHex("8a40bfaa73256b60764c1bf40675a99083efb075"))] = AddressState(u256(1) << 200, 0);
s_ret[Address(fromUserHex("93658b04240e4bd4046fd2d6d417d20f146f4b43"))] = AddressState(u256(1) << 200, 0);
s_ret[Address(fromUserHex("1e12515ce3e0f817a4ddef9ca55788a1d66bd2df"))] = AddressState(u256(1) << 200, 0);
s_ret[Address(fromUserHex("80c01a26338f0d905e295fccb71fa9ea849ffa12"))] = AddressState(u256(1) << 200, 0);
s_ret[Address(fromUserHex("8a40bfaa73256b60764c1bf40675a99083efb075"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromUserHex("e6716f9544a56c530d868e4bfbacb172315bdead"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromUserHex("1e12515ce3e0f817a4ddef9ca55788a1d66bd2df"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
s_ret[Address(fromUserHex("1a26338f0d905e295fccb71fa9ea849ffa12aaf4"))] = AddressState(u256(1) << 200, 0, AddressType::Normal);
}
return s_ret;
}
@ -90,8 +70,8 @@ State::State(Address _coinbaseAddress, Overlay const& _db):
m_state(&m_db),
m_ourAddress(_coinbaseAddress)
{
m_blockReward = u256(15000000000) * 100000000;
m_fees.setMultiplier(u256(100000) * 1000000000);
m_blockReward = 1500 * finney;
m_fees.setMultiplier(100 * szabo);
secp256k1_start();
@ -111,6 +91,7 @@ State::State(State const& _s):
m_db(_s.m_db),
m_state(&m_db, _s.m_state.root()),
m_transactions(_s.m_transactions),
m_transactionSet(_s.m_transactionSet),
m_cache(_s.m_cache),
m_previousBlock(_s.m_previousBlock),
m_currentBlock(_s.m_currentBlock),
@ -126,6 +107,7 @@ State& State::operator=(State const& _s)
m_db = _s.m_db;
m_state.open(&m_db, _s.m_state.root());
m_transactions = _s.m_transactions;
m_transactionSet = _s.m_transactionSet;
m_cache = _s.m_cache;
m_previousBlock = _s.m_previousBlock;
m_currentBlock = _s.m_currentBlock;
@ -136,17 +118,6 @@ State& State::operator=(State const& _s)
return *this;
}
void FeeStructure::setMultiplier(u256 _x)
{
m_stepFee = c_stepFee * _x;
m_dataFee = c_dataFee * _x;
m_memoryFee = c_memoryFee * _x;
m_extroFee = c_extroFee * _x;
m_cryptoFee = c_cryptoFee * _x;
m_newContractFee = c_newContractFee * _x;
m_txFee = c_txFee * _x;
}
void State::ensureCached(Address _a, bool _requireMemory, bool _forceCreate) const
{
auto it = m_cache.find(_a);
@ -171,13 +142,17 @@ void State::ensureCached(Address _a, bool _requireMemory, bool _forceCreate) con
{
// Populate memory.
assert(it->second.type() == AddressType::Contract);
TrieDB<u256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't alter the overlay! :)
map<u256, u256>& mem = it->second.takeMemory();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't alter the overlay! :)
map<u256, u256>& mem = it->second.setHaveMemory();
for (auto const& i: memdb)
#ifdef __clang__
if (mem.find(i.first) == mem.end())
mem.insert(make_pair(i.first, RLP(i.second).toInt<u256>()));
else
mem.at(i.first) = RLP(i.second).toInt<u256>();
#else
mem[i.first] = RLP(i.second).toInt<u256>();
#endif
}
}
@ -266,11 +241,18 @@ map<Address, u256> State::addresses() const
void State::resetCurrent()
{
m_transactions.clear();
m_transactionSet.clear();
m_cache.clear();
m_currentBlock = BlockInfo();
m_currentBlock.coinbaseAddress = m_ourAddress;
m_currentBlock.stateRoot = m_previousBlock.stateRoot;
m_currentBlock.parentHash = m_previousBlock.hash;
m_currentBlock.sha3Transactions = h256();
m_currentBlock.sha3Uncles = h256();
// Update timestamp according to clock.
m_currentBlock.timestamp = time(0);
m_state.setRoot(m_currentBlock.stateRoot);
}
@ -279,7 +261,9 @@ bool State::cull(TransactionQueue& _tq) const
bool ret = false;
auto ts = _tq.transactions();
for (auto const& i: ts)
if (!m_transactions.count(i.first))
{
if (!m_transactionSet.count(i.first))
{
try
{
Transaction t(i.second);
@ -294,6 +278,8 @@ bool State::cull(TransactionQueue& _tq) const
_tq.drop(i.first);
ret = true;
}
}
}
return ret;
}
@ -303,7 +289,9 @@ bool State::sync(TransactionQueue& _tq)
bool ret = false;
auto ts = _tq.transactions();
for (auto const& i: ts)
if (!m_transactions.count(i.first))
{
if (!m_transactionSet.count(i.first))
{
// don't have it yet! Execute it now.
try
{
@ -325,6 +313,8 @@ bool State::sync(TransactionQueue& _tq)
_tq.drop(i.first);
ret = true;
}
}
}
return ret;
}
@ -356,6 +346,9 @@ u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent, bool _
if (m_currentBlock.parentHash != m_previousBlock.hash)
throw InvalidParentHash();
// cnote << "playback begins:" << m_state.root();
// cnote << m_state;
// All ok with the block generally. Play back the transactions now...
for (auto const& i: RLP(_block)[1])
execute(i.data());
@ -385,9 +378,10 @@ u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent, bool _
{
cwarn << "Bad state root!";
cnote << "Given to be:" << m_currentBlock.stateRoot;
cnote << TrieDB<Address, Overlay>(&m_db, m_currentBlock.stateRoot);
cnote << "Calculated to be:" << rootHash();
cnote << m_state;
cnote << TrieDB<Address, Overlay>(&m_db, m_currentBlock.stateRoot);
cnote << *this;
// Rollback the trie.
m_db.rollback();
throw InvalidStateRoot();
@ -414,14 +408,15 @@ u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent, bool _
// (i.e. all the transactions we executed).
void State::commitToMine(BlockChain const& _bc)
{
if (m_previousBlock.hash != m_committedPreviousHash)
if (m_currentBlock.sha3Transactions != h256() || m_currentBlock.sha3Uncles != h256())
{
m_committedPreviousHash = m_previousBlock.hash;
cnote << "Commiting to mine on" << m_previousBlock.hash;
Addresses uncleAddresses;
for (auto i: RLP(m_currentUncles))
uncleAddresses.push_back(i[2].toHash<Address>());
unapplyRewards(uncleAddresses);
}
if (m_currentBlock.sha3Transactions != h256() || m_currentBlock.sha3Uncles != h256())
return;
cnote << "Commiting to mine on" << m_previousBlock.hash;
RLPStream uncles;
Addresses uncleAddresses;
@ -448,7 +443,7 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream txs(m_transactions.size());
for (auto const& i: m_transactions)
i.second.fillStream(txs);
i.fillStream(txs);
txs.swapOut(m_currentTxs);
uncles.swapOut(m_currentUncles);
@ -459,15 +454,16 @@ void State::commitToMine(BlockChain const& _bc)
// Commit any and all changes to the trie that are in the cache, then update the state root accordingly.
commit();
cnote << "stateRoot:" << m_state.root();
// cnote << m_state;
// cnote << *this;
m_currentBlock.stateRoot = m_state.root();
m_currentBlock.parentHash = m_previousBlock.hash;
}
MineInfo State::mine(uint _msTimeout)
{
// Update timestamp according to clock.
m_currentBlock.timestamp = time(0);
// Update difficulty according to timestamp.
m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock);
@ -577,8 +573,17 @@ u256 State::contractMemory(Address _id, u256 _memory) const
return mit->second;
}
// Memory not cached - just grab one item from the DB rather than cache the lot.
TrieDB<u256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't change the overlay! :)
return RLP(memdb.at(_memory)).toInt<u256>(); // TODO: CHECK: check if this is actually an RLP decode
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&m_db), it->second.oldRoot()); // promise we won't change the overlay! :)
string ret = memdb.at(_memory);
return ret.size() ? RLP(ret).toInt<u256>() : 0;
}
map<u256, u256> const& State::contractMemory(Address _contract) const
{
if (!isContractAddress(_contract))
return EmptyMapU256U256;
ensureCached(_contract, true, true);
return m_cache[_contract].memory();
}
void State::execute(bytesConstRef _rlp)
@ -591,7 +596,8 @@ void State::execute(bytesConstRef _rlp)
// NOTE: Here, contract-originated transactions will not get added to the transaction list.
// If this is wrong, move this line into execute(Transaction const& _t, Address _sender) and
// don't forget to allow unsigned transactions in the tx list if they concur with the script execution.
m_transactions.insert(make_pair(t.sha3(), t));
m_transactions.push_back(t);
m_transactionSet.insert(t.sha3());
}
void State::applyRewards(Addresses const& _uncleAddresses)
@ -599,579 +605,125 @@ void State::applyRewards(Addresses const& _uncleAddresses)
u256 r = m_blockReward;
for (auto const& i: _uncleAddresses)
{
addBalance(i, m_blockReward * 4 / 3);
addBalance(i, m_blockReward * 3 / 4);
r += m_blockReward / 8;
}
addBalance(m_currentBlock.coinbaseAddress, r);
}
void State::unapplyRewards(Addresses const& _uncleAddresses)
{
u256 r = m_blockReward;
for (auto const& i: _uncleAddresses)
{
subBalance(i, m_blockReward * 3 / 4);
r += m_blockReward / 8;
}
subBalance(m_currentBlock.coinbaseAddress, r);
}
void State::executeBare(Transaction const& _t, Address _sender)
{
#if ETH_DEBUG
commit();
clog(StateChat) << "State:" << rootHash();
clog(StateChat) << "Executing TX:" << _t;
#endif
// Entry point for a contract-originated transaction.
// Ignore invalid transactions.
auto nonceReq = transactionsFrom(_sender);
if (_t.nonce != nonceReq)
{
clog(StateChat) << "Invalid Nonce.";
throw InvalidNonce(nonceReq, _t.nonce);
}
unsigned nonZeroData = 0;
for (auto i: _t.data)
if (i)
nonZeroData++;
u256 fee = _t.receiveAddress ? m_fees.m_txFee : (nonZeroData * m_fees.m_memoryFee + m_fees.m_newContractFee);
// Not considered invalid - just pointless.
u256 fee = _t.receiveAddress ? m_fees.m_txFee : (_t.data.size() * m_fees.m_memoryFee + m_fees.m_newContractFee);
if (balance(_sender) < _t.value + fee)
{
clog(StateChat) << "Not enough cash.";
throw NotEnoughCash();
// Increment associated nonce for sender.
noteSending(_sender);
}
if (_t.receiveAddress)
{
// Increment associated nonce for sender.
noteSending(_sender);
// Pay...
subBalance(_sender, _t.value + fee);
addBalance(_t.receiveAddress, _t.value);
if (isContractAddress(_t.receiveAddress))
{
MinerFeeAdder feeAdder({this, 0}); // will add fee on destruction.
execute(_t.receiveAddress, _sender, _t.value, _t.data, &feeAdder.fee);
// Once we get here, there's no going back.
try
{
MinerFeeAdder feeAdder({this, 0}); // will add fee on destruction.
execute(_t.receiveAddress, _sender, _t.value, _t.data, &feeAdder.fee);
}
catch (VMException const& _e)
{
clog(StateChat) << "VM Exception: " << _e.description();
}
catch (Exception const& _e)
{
clog(StateChat) << "Exception in VM: " << _e.description();
}
catch (std::exception const& _e)
{
clog(StateChat) << "std::exception in VM: " << _e.what();
}
}
}
else
{
#if ETH_SENDER_PAYS_SETUP
if (balance(_sender) < _t.value + fee)
#else
if (_t.value < fee)
#endif
throw NotEnoughCash();
Address newAddress = low160(_t.sha3());
Address newAddress = right160(_t.sha3());
if (isContractAddress(newAddress) || isNormalAddress(newAddress))
{
clog(StateChat) << "Contract address collision.";
throw ContractAddressCollision();
}
// All OK - set it up.
m_cache[newAddress] = AddressState(0, 0, sha3(RLPNull));
auto& mem = m_cache[newAddress].takeMemory();
// Increment associated nonce for sender.
noteSending(_sender);
// Pay out of sender...
subBalance(_sender, _t.value + fee);
// Set up new account...
m_cache[newAddress] = AddressState(_t.value, 0, AddressType::Contract);
auto& mem = m_cache[newAddress].memory();
for (uint i = 0; i < _t.data.size(); ++i)
#ifdef __clang__
if (mem.find(i) == mem.end())
mem.insert(make_pair(i, _t.data[i]));
else
mem.at(i) = _t.data[i];
#if ETH_SENDER_PAYS_SETUP
subBalance(_sender, _t.value + fee);
addBalance(newAddress, _t.value);
#else
subBalance(_sender, _t.value);
addBalance(newAddress, _t.value - fee);
mem[i] = _t.data[i];
#endif
}
}
// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash.
// Currently we just pull out the left (high-order in BE) 160-bits.
// TODO: CHECK: check that this is correct.
inline Address asAddress(u256 _item)
{
return left160(h256(_item));
#if ETH_DEBUG
commit();
clog(StateChat) << "New state:" << rootHash();
#endif
}
void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256s const& _txData, u256* _totalFee)
{
std::vector<u256> stack;
// Set up some local functions.
auto require = [&](u256 _n)
{
if (stack.size() < _n)
throw StackTooSmall(_n, stack.size());
};
ensureCached(_myAddress, true, true);
auto& myMemory = m_cache[_myAddress].takeMemory();
auto mem = [&](u256 _n) -> u256
{
auto i = myMemory.find(_n);
return i == myMemory.end() ? 0 : i->second;
};
auto setMem = [&](u256 _n, u256 _v)
{
if (_v)
{
auto it = myMemory.find(_n);
if (it == myMemory.end())
myMemory.insert(make_pair(_n, _v));
else
myMemory.at(_n) = _v;
}
else
myMemory.erase(_n);
};
u256 curPC = 0;
u256 nextPC = 1;
u256 stepCount = 0;
for (bool stopped = false; !stopped; curPC = nextPC, nextPC = curPC + 1)
{
stepCount++;
bigint minerFee = stepCount > 16 ? m_fees.m_stepFee : 0;
bigint voidFee = 0;
auto rawInst = mem(curPC);
if (rawInst > 0xff)
throw BadInstruction();
Instruction inst = (Instruction)(uint8_t)rawInst;
switch (inst)
{
case Instruction::STORE:
require(2);
if (!mem(stack.back()) && stack[stack.size() - 2])
voidFee += m_fees.m_memoryFee;
if (mem(stack.back()) && !stack[stack.size() - 2])
voidFee -= m_fees.m_memoryFee;
// continue on to...
case Instruction::LOAD:
minerFee += m_fees.m_dataFee;
break;
case Instruction::EXTRO:
case Instruction::BALANCE:
minerFee += m_fees.m_extroFee;
break;
case Instruction::MKTX:
minerFee += m_fees.m_txFee;
break;
case Instruction::SHA256:
case Instruction::RIPEMD160:
case Instruction::ECMUL:
case Instruction::ECADD:
case Instruction::ECSIGN:
case Instruction::ECRECOVER:
case Instruction::ECVALID:
minerFee += m_fees.m_cryptoFee;
break;
default:
break;
}
if (minerFee + voidFee > balance(_myAddress))
throw NotEnoughCash();
subBalance(_myAddress, minerFee + voidFee);
*_totalFee += (u256)minerFee;
switch (inst)
{
case Instruction::ADD:
//pops two items and pushes S[-1] + S[-2] mod 2^256.
require(2);
stack[stack.size() - 2] += stack.back();
stack.pop_back();
break;
case Instruction::MUL:
//pops two items and pushes S[-1] * S[-2] mod 2^256.
require(2);
stack[stack.size() - 2] *= stack.back();
stack.pop_back();
break;
case Instruction::SUB:
require(2);
stack[stack.size() - 2] = stack.back() - stack[stack.size() - 2];
stack.pop_back();
break;
case Instruction::DIV:
require(2);
stack[stack.size() - 2] = stack.back() / stack[stack.size() - 2];
stack.pop_back();
break;
case Instruction::SDIV:
require(2);
(s256&)stack[stack.size() - 2] = (s256&)stack.back() / (s256&)stack[stack.size() - 2];
stack.pop_back();
break;
case Instruction::MOD:
require(2);
stack[stack.size() - 2] = stack.back() % stack[stack.size() - 2];
stack.pop_back();
break;
case Instruction::SMOD:
require(2);
(s256&)stack[stack.size() - 2] = (s256&)stack.back() % (s256&)stack[stack.size() - 2];
stack.pop_back();
break;
case Instruction::EXP:
{
// TODO: better implementation?
require(2);
auto n = stack.back();
auto x = stack[stack.size() - 2];
stack.pop_back();
for (u256 i = 0; i < x; ++i)
n *= n;
stack.back() = n;
break;
}
case Instruction::NEG:
require(1);
stack.back() = ~(stack.back() - 1);
break;
case Instruction::LT:
require(2);
stack[stack.size() - 2] = stack.back() < stack[stack.size() - 2] ? 1 : 0;
stack.pop_back();
break;
case Instruction::LE:
require(2);
stack[stack.size() - 2] = stack.back() <= stack[stack.size() - 2] ? 1 : 0;
stack.pop_back();
break;
case Instruction::GT:
require(2);
stack[stack.size() - 2] = stack.back() > stack[stack.size() - 2] ? 1 : 0;
stack.pop_back();
break;
case Instruction::GE:
require(2);
stack[stack.size() - 2] = stack.back() >= stack[stack.size() - 2] ? 1 : 0;
stack.pop_back();
break;
case Instruction::EQ:
require(2);
stack[stack.size() - 2] = stack.back() == stack[stack.size() - 2] ? 1 : 0;
stack.pop_back();
break;
case Instruction::NOT:
require(1);
stack.back() = stack.back() ? 0 : 1;
stack.pop_back();
break;
case Instruction::MYADDRESS:
stack.push_back((u160)_myAddress);
break;
case Instruction::TXSENDER:
stack.push_back((u160)_txSender);
break;
case Instruction::TXVALUE:
stack.push_back(_txValue);
break;
case Instruction::TXDATAN:
stack.push_back(_txData.size());
break;
case Instruction::TXDATA:
require(1);
stack.back() = stack.back() < _txData.size() ? _txData[(uint)stack.back()] : 0;
break;
case Instruction::BLK_PREVHASH:
stack.push_back(m_previousBlock.hash);
break;
case Instruction::BLK_COINBASE:
stack.push_back((u160)m_currentBlock.coinbaseAddress);
break;
case Instruction::BLK_TIMESTAMP:
stack.push_back(m_currentBlock.timestamp);
break;
case Instruction::BLK_NUMBER:
stack.push_back(m_currentNumber);
break;
case Instruction::BLK_DIFFICULTY:
stack.push_back(m_currentBlock.difficulty);
break;
case Instruction::SHA256:
{
uint s = (uint)min(stack.back(), (u256)(stack.size() - 1) * 32);
stack.pop_back();
CryptoPP::SHA256 digest;
uint i = 0;
for (; s; s = (s >= 32 ? s - 32 : 0), i += 32)
{
bytes b = toBigEndian(stack.back());
digest.Update(b.data(), (int)min<u256>(32, s)); // b.size() == 32
stack.pop_back();
}
array<byte, 32> final;
digest.TruncatedFinal(final.data(), 32);
stack.push_back(fromBigEndian<u256>(final));
break;
}
case Instruction::RIPEMD160:
{
uint s = (uint)min(stack.back(), (u256)(stack.size() - 1) * 32);
stack.pop_back();
CryptoPP::RIPEMD160 digest;
uint i = 0;
for (; s; s = (s >= 32 ? s - 32 : 0), i += 32)
{
bytes b = toBigEndian(stack.back());
digest.Update(b.data(), (int)min<u256>(32, s)); // b.size() == 32
stack.pop_back();
}
array<byte, 20> final;
digest.TruncatedFinal(final.data(), 20);
// NOTE: this aligns to right of 256-bit container (low-order bytes).
// This won't work if they're treated as byte-arrays and thus left-aligned in a 256-bit container.
stack.push_back((u256)fromBigEndian<u160>(final));
break;
}
case Instruction::ECMUL:
{
// ECMUL - pops three items.
// If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-1],S[-2]) * S[-3], using (0,0) as the point at infinity.
// Otherwise, pushes (0,0).
require(3);
bytes pub(1, 4);
pub += toBigEndian(stack[stack.size() - 2]);
pub += toBigEndian(stack.back());
stack.pop_back();
stack.pop_back();
bytes x = toBigEndian(stack.back());
stack.pop_back();
if (secp256k1_ecdsa_pubkey_verify(pub.data(), (int)pub.size())) // TODO: Check both are less than P.
{
secp256k1_ecdsa_pubkey_tweak_mul(pub.data(), (int)pub.size(), x.data());
stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(1, 32)));
stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(33, 32)));
}
else
{
stack.push_back(0);
stack.push_back(0);
}
break;
}
case Instruction::ECADD:
{
// ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (0,0).
require(4);
bytes pub(1, 4);
pub += toBigEndian(stack[stack.size() - 2]);
pub += toBigEndian(stack.back());
stack.pop_back();
stack.pop_back();
bytes tweak(1, 4);
tweak += toBigEndian(stack[stack.size() - 2]);
tweak += toBigEndian(stack.back());
stack.pop_back();
stack.pop_back();
if (secp256k1_ecdsa_pubkey_verify(pub.data(),(int) pub.size()) && secp256k1_ecdsa_pubkey_verify(tweak.data(),(int) tweak.size()))
{
secp256k1_ecdsa_pubkey_tweak_add(pub.data(), (int)pub.size(), tweak.data());
stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(1, 32)));
stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(33, 32)));
}
else
{
stack.push_back(0);
stack.push_back(0);
}
break;
}
case Instruction::ECSIGN:
{
require(2);
bytes sig(64);
int v = 0;
u256 msg = stack.back();
stack.pop_back();
u256 priv = stack.back();
stack.pop_back();
bytes nonce = toBigEndian(Transaction::kFromMessage(msg, priv));
if (!secp256k1_ecdsa_sign_compact(toBigEndian(msg).data(), 64, sig.data(), toBigEndian(priv).data(), nonce.data(), &v))
throw InvalidSignature();
stack.push_back(v + 27);
stack.push_back(fromBigEndian<u256>(bytesConstRef(&sig).cropped(0, 32)));
stack.push_back(fromBigEndian<u256>(bytesConstRef(&sig).cropped(32)));
break;
}
case Instruction::ECRECOVER:
{
require(4);
bytes sig = toBigEndian(stack[stack.size() - 2]) + toBigEndian(stack.back());
stack.pop_back();
stack.pop_back();
int v = (int)stack.back();
stack.pop_back();
bytes msg = toBigEndian(stack.back());
stack.pop_back();
byte pubkey[65];
int pubkeylen = 65;
if (secp256k1_ecdsa_recover_compact(msg.data(), (int)msg.size(), sig.data(), pubkey, &pubkeylen, 0, v - 27))
{
stack.push_back(0);
stack.push_back(0);
}
else
{
stack.push_back(fromBigEndian<u256>(bytesConstRef(&pubkey[1], 32)));
stack.push_back(fromBigEndian<u256>(bytesConstRef(&pubkey[33], 32)));
}
break;
}
case Instruction::ECVALID:
{
require(2);
bytes pub(1, 4);
pub += toBigEndian(stack[stack.size() - 2]);
pub += toBigEndian(stack.back());
stack.pop_back();
stack.pop_back();
stack.back() = secp256k1_ecdsa_pubkey_verify(pub.data(), (int)pub.size()) ? 1 : 0;
break;
}
case Instruction::SHA3:
{
uint s = (uint)min(stack.back(), (u256)(stack.size() - 1) * 32);
stack.pop_back();
CryptoPP::SHA3_256 digest;
uint i = 0;
for (; s; s = (s >= 32 ? s - 32 : 0), i += 32)
{
bytes b = toBigEndian(stack.back());
digest.Update(b.data(), (int)min<u256>(32, s)); // b.size() == 32
stack.pop_back();
}
array<byte, 32> final;
digest.TruncatedFinal(final.data(), 32);
stack.push_back(fromBigEndian<u256>(final));
break;
}
case Instruction::PUSH:
{
stack.push_back(mem(curPC + 1));
nextPC = curPC + 2;
break;
}
case Instruction::POP:
require(1);
stack.pop_back();
break;
case Instruction::DUP:
require(1);
stack.push_back(stack.back());
break;
case Instruction::DUPN:
{
auto s = mem(curPC + 1);
if (s == 0 || s > stack.size())
throw OperandOutOfRange(1, stack.size(), s);
stack.push_back(stack[stack.size() - (uint)s]);
nextPC = curPC + 2;
break;
}
case Instruction::SWAP:
{
require(2);
auto d = stack.back();
stack.back() = stack[stack.size() - 2];
stack[stack.size() - 2] = d;
break;
}
case Instruction::SWAPN:
{
require(1);
auto d = stack.back();
auto s = mem(curPC + 1);
if (s == 0 || s > stack.size())
throw OperandOutOfRange(1, stack.size(), s);
stack.back() = stack[stack.size() - (uint)s];
stack[stack.size() - (uint)s] = d;
nextPC = curPC + 2;
break;
}
case Instruction::LOAD:
require(1);
stack.back() = mem(stack.back());
break;
case Instruction::STORE:
require(2);
setMem(stack.back(), stack[stack.size() - 2]);
stack.pop_back();
stack.pop_back();
break;
case Instruction::JMP:
require(1);
nextPC = stack.back();
stack.pop_back();
break;
case Instruction::JMPI:
require(2);
if (stack.back())
nextPC = stack[stack.size() - 2];
stack.pop_back();
stack.pop_back();
break;
case Instruction::IND:
stack.push_back(curPC);
break;
case Instruction::EXTRO:
{
require(2);
auto memoryAddress = stack.back();
stack.pop_back();
Address contractAddress = asAddress(stack.back());
stack.back() = contractMemory(contractAddress, memoryAddress);
break;
}
case Instruction::BALANCE:
{
require(1);
stack.back() = balance(asAddress(stack.back()));
break;
}
case Instruction::MKTX:
{
require(4);
Transaction t;
t.receiveAddress = asAddress(stack.back());
stack.pop_back();
t.value = stack.back();
stack.pop_back();
auto itemCount = stack.back();
stack.pop_back();
if (stack.size() < itemCount)
throw OperandOutOfRange(0, stack.size(), itemCount);
t.data.reserve((uint)itemCount);
for (auto i = 0; i < itemCount; ++i)
{
t.data.push_back(stack.back());
stack.pop_back();
}
t.nonce = transactionsFrom(_myAddress);
executeBare(t, _myAddress);
break;
}
case Instruction::SUICIDE:
{
require(1);
Address dest = asAddress(stack.back());
u256 minusVoidFee = myMemory.size() * m_fees.m_memoryFee;
addBalance(dest, balance(_myAddress) + minusVoidFee);
m_cache[_myAddress].kill();
// ...follow through to...
}
case Instruction::STOP:
return;
default:
throw BadInstruction();
}
}
VM vm;
ExtVM evm(*this, _myAddress, _txSender, _txValue, _txData);
vm.go(evm);
*_totalFee = vm.runFee();
}

162
libethereum/State.h

@ -32,30 +32,23 @@
#include "AddressState.h"
#include "Transaction.h"
#include "TrieDB.h"
#include "FeeStructure.h"
#include "Dagger.h"
#include "ExtVMFace.h"
namespace eth
{
class BlockChain;
extern const u256 c_genesisDifficulty;
extern u256 c_genesisDifficulty;
std::map<Address, AddressState> const& genesisState();
#define ETH_SENDER_PAYS_SETUP 1
static const std::map<u256, u256> EmptyMapU256U256;
struct FeeStructure
{
/// The fee structure. Values yet to be agreed on...
void setMultiplier(u256 _x); ///< The current block multiplier.
u256 m_stepFee;
u256 m_dataFee;
u256 m_memoryFee;
u256 m_extroFee;
u256 m_cryptoFee;
u256 m_newContractFee;
u256 m_txFee;
};
struct StateChat: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 4; };
class ExtVM;
/**
* @brief Model of the current state of the ledger.
@ -64,6 +57,9 @@ struct FeeStructure
*/
class State
{
template <unsigned T> friend class UnitTest;
friend class ExtVM;
public:
/// Construct state object.
State(Address _coinbaseAddress, Overlay const& _db);
@ -150,6 +146,10 @@ public:
/// @returns 0 if no contract exists at that address.
u256 contractMemory(Address _contract, u256 _memory) const;
/// Get the memory of a contract.
/// @returns std::map<u256, u256> if no contract exists at that address.
std::map<u256, u256> const& contractMemory(Address _contract) const;
/// Note that the given address is sending a transaction and thus increment the associated ticker.
void noteSending(Address _id);
@ -161,10 +161,7 @@ public:
h256 rootHash() const { return m_state.root(); }
/// Get the list of pending transactions.
std::map<h256, Transaction> const& pending() const { return m_transactions; }
/// Finalise the block, applying the earned rewards.
void applyRewards(Addresses const& _uncleAddresses);
Transactions const& pending() const { return m_transactions; }
/// Execute all transactions within a given block.
/// @returns the additional total difficulty.
@ -214,9 +211,16 @@ private:
/// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock).
void resetCurrent();
/// Finalise the block, applying the earned rewards.
void applyRewards(Addresses const& _uncleAddresses);
/// Unfinalise the block, unapplying the earned rewards.
void unapplyRewards(Addresses const& _uncleAddresses);
Overlay m_db; ///< Our overlay for the state tree.
TrieDB<Address, Overlay> m_state; ///< Our state tree, as an Overlay DB.
std::map<h256, Transaction> m_transactions; ///< The current list of transactions that we've included in the state.
Transactions m_transactions; ///< The current list of transactions that we've included in the state.
std::set<h256> m_transactionSet; ///< The set of transaction hashes that we've included in the state.
mutable std::map<Address, AddressState> m_cache; ///< Our address cache. This stores the states of each address that has (or at least might have) been changed.
@ -224,7 +228,6 @@ private:
BlockInfo m_currentBlock; ///< The current block's information.
bytes m_currentBytes; ///< The current block.
uint m_currentNumber;
h256 m_committedPreviousHash; ///< Hash of previous block that we are committing to mine.
bytes m_currentTxs;
bytes m_currentUncles;
@ -241,17 +244,98 @@ private:
friend std::ostream& operator<<(std::ostream& _out, State const& _s);
};
class ExtVM: public ExtVMFace
{
public:
ExtVM(State& _s, Address _myAddress, Address _txSender, u256 _txValue, u256s const& _txData):
ExtVMFace(_myAddress, _txSender, _txValue, _txData, _s.m_fees, _s.m_previousBlock, _s.m_currentBlock, _s.m_currentNumber), m_s(_s)
{
m_s.ensureCached(_myAddress, true, true);
m_store = &(m_s.m_cache[_myAddress].memory());
}
u256 store(u256 _n)
{
auto i = m_store->find(_n);
return i == m_store->end() ? 0 : i->second;
}
void setStore(u256 _n, u256 _v)
{
if (_v)
{
#ifdef __clang__
auto it = m_store->find(_n);
if (it == m_store->end())
m_store->insert(std::make_pair(_n, _v));
else
m_store->at(_n) = _v;
#else
(*m_store)[_n] = _v;
#endif
}
else
m_store->erase(_n);
}
void payFee(bigint _f)
{
if (_f > m_s.balance(myAddress))
throw NotEnoughCash();
m_s.subBalance(myAddress, _f);
}
void mktx(Transaction& _t)
{
_t.nonce = m_s.transactionsFrom(myAddress);
m_s.executeBare(_t, myAddress);
}
u256 balance(Address _a) { return m_s.balance(_a); }
u256 txCount(Address _a) { return m_s.transactionsFrom(_a); }
u256 extro(Address _a, u256 _pos) { return m_s.contractMemory(_a, _pos); }
u256 extroPrice(Address _a) { return 0; }
void suicide(Address _a)
{
m_s.addBalance(_a, m_s.balance(myAddress) + m_store->size() * fees.m_memoryFee);
m_s.m_cache[myAddress].kill();
}
private:
State& m_s;
std::map<u256, u256>* m_store;
};
inline std::ostream& operator<<(std::ostream& _out, State const& _s)
{
_out << "--- " << _s.rootHash() << std::endl;
std::set<Address> d;
for (auto const& i: TrieDB<Address, Overlay>(const_cast<Overlay*>(&_s.m_db), _s.m_currentBlock.stateRoot))
for (auto const& i: TrieDB<Address, Overlay>(const_cast<Overlay*>(&_s.m_db), _s.rootHash()))
{
auto it = _s.m_cache.find(i.first);
if (it == _s.m_cache.end())
{
RLP r(i.second);
_out << "[ " << (r.itemCount() == 3 ? "CONTRACT] " : " NORMAL] ") << i.first << ": " << std::dec << r[1].toInt<u256>() << "@" << r[0].toInt<u256>() << std::endl;
_out << "[ " << (r.itemCount() == 3 ? "CONTRACT] " : " NORMAL] ") << i.first << ": " << std::dec << r[1].toInt<u256>() << "@" << r[0].toInt<u256>();
if (r.itemCount() == 3)
{
_out << " *" << r[2].toHash<h256>();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&_s.m_db), r[2].toHash<h256>()); // promise we won't alter the overlay! :)
std::map<u256, u256> mem;
for (auto const& j: memdb)
{
_out << std::endl << " [" << j.first << ":" << asHex(j.second) << "]";
#ifdef __clang__
auto mFinder = mem.find(j.first);
if (mFinder == mem.end())
mem.insert(std::make_pair(j.first, RLP(j.second).toInt<u256>()));
else
mFinder->second = RLP(j.second).toInt<u256>();
#else
mem[j.first] = RLP(j.second).toInt<u256>();
#endif
}
_out << std::endl << mem;
}
_out << std::endl;
}
else
d.insert(i.first);
@ -260,7 +344,37 @@ inline std::ostream& operator<<(std::ostream& _out, State const& _s)
if (i.second.type() == AddressType::Dead)
_out << "[XXX " << i.first << std::endl;
else
_out << (d.count(i.first) ? "[ ! " : "[ * ") << (i.second.type() == AddressType::Contract ? "CONTRACT] " : " NORMAL] ") << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance() << std::endl;
{
_out << (d.count(i.first) ? "[ ! " : "[ * ") << (i.second.type() == AddressType::Contract ? "CONTRACT] " : " NORMAL] ") << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance();
if (i.second.type() == AddressType::Contract)
{
if (i.second.haveMemory())
{
_out << std::endl << i.second.memory();
}
else
{
_out << " *" << i.second.oldRoot();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&_s.m_db), i.second.oldRoot()); // promise we won't alter the overlay! :)
std::map<u256, u256> mem;
for (auto const& j: memdb)
{
_out << std::endl << " [" << j.first << ":" << asHex(j.second) << "]";
#ifdef __clang__
auto mFinder = mem.find(j.first);
if (mFinder == mem.end())
mem.insert(std::make_pair(j.first, RLP(j.second).toInt<u256>()));
else
mFinder->second = RLP(j.second).toInt<u256>();
#else
mem[j.first] = RLP(j.second).toInt<u256>();
#endif
}
_out << std::endl << mem;
}
}
_out << std::endl;
}
return _out;
}
@ -278,7 +392,7 @@ void commit(std::map<Address, AddressState> const& _cache, DB& _db, TrieDB<Addre
{
if (i.second.haveMemory())
{
TrieDB<u256, DB> memdb(&_db);
TrieDB<h256, DB> memdb(&_db);
memdb.init();
for (auto const& j: i.second.memory())
if (j.second)

12
libethereum/Transaction.cpp

@ -40,6 +40,18 @@ Transaction::Transaction(bytesConstRef _rlpData)
vrs = Signature{ rlp[4].toInt<byte>(), rlp[5].toInt<u256>(), rlp[6].toInt<u256>() };
}
Address Transaction::safeSender() const noexcept
{
try
{
return sender();
}
catch (...)
{
return Address();
}
}
Address Transaction::sender() const
{
secp256k1_start();

14
libethereum/Transaction.h

@ -41,12 +41,16 @@ struct Transaction
Transaction(bytesConstRef _rlp);
Transaction(bytes const& _rlp): Transaction(&_rlp) {}
bool operator==(Transaction const& _c) const { return receiveAddress == _c.receiveAddress && value == _c.value && data == _c.data; }
bool operator!=(Transaction const& _c) const { return !operator==(_c); }
u256 nonce;
Address receiveAddress;
u256 value;
u256s data;
Signature vrs;
Address safeSender() const noexcept;
Address sender() const;
void sign(Secret _priv);
@ -63,11 +67,17 @@ using Transactions = std::vector<Transaction>;
inline std::ostream& operator<<(std::ostream& _out, Transaction const& _t)
{
_out << "{" << _t.receiveAddress << "/" << _t.nonce << "*" << _t.value;
_out << "{";
if (_t.receiveAddress)
_out << _t.receiveAddress.abridged();
else
_out << "[CREATE]";
_out << "/" << _t.nonce << "*" << _t.value;
Address s;
try
{
_out << "<-" << _t.sender();
_out << "<-" << _t.sender().abridged();
}
catch (...) {}
_out << "}";

6
libethereum/TrieCommon.cpp

@ -110,14 +110,14 @@ std::string hexPrefixEncode(bytesConstRef _d1, uint _o1, bytesConstRef _d2, uint
return ret;
}
byte uniqueInUse(RLP const& _orig, byte _except)
byte uniqueInUse(RLP const& _orig, byte except)
{
byte used = 255;
for (unsigned i = 0; i < 17; ++i)
if (i != _except && !_orig[i].isEmpty())
if (i != except && !_orig[i].isEmpty())
{
if (used == 255)
used = i;
used = (byte)i;
else
return 255;
}

4
libethereum/TrieCommon.h

@ -66,7 +66,7 @@ inline bool isLeaf(RLP const& _twoItem)
{
assert(_twoItem.isList() && _twoItem.itemCount() == 2);
auto pl = _twoItem[0].payload();
return (pl[0] & 0x20);
return (pl[0] & 0x20) != 0;
}
inline NibbleSlice keyOf(bytesConstRef _hpe)
@ -84,7 +84,7 @@ inline NibbleSlice keyOf(RLP const& _twoItem)
return keyOf(_twoItem[0].payload());
}
byte uniqueInUse(RLP const& _orig, byte _except);
byte uniqueInUse(RLP const& _orig, byte except);
std::string hexPrefixEncode(bytes const& _hexVector, bool _leaf = false, int _begin = 0, int _end = -1);
std::string hexPrefixEncode(bytesConstRef _data, bool _leaf, int _beginNibble, int _endNibble, uint _offset);
std::string hexPrefixEncode(bytesConstRef _d1, uint _o1, bytesConstRef _d2, uint _o2, bool _leaf);

21
libethereum/TrieDB.h

@ -76,10 +76,10 @@ public:
ldb::DB* db() const { return m_db.get(); }
void setDB(ldb::DB* _db, bool _clearOverlay = true) { m_db = std::shared_ptr<ldb::DB>(_db); if (_clearOverlay) m_over.clear(); }
void commit() { for (auto const& i: m_over) m_db->Put(m_writeOptions, ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.data(), i.second.size())); m_over.clear(); m_refCount.clear(); }
void commit() { if (m_db) { for (auto const& i: m_over) m_db->Put(m_writeOptions, ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.data(), i.second.size())); m_over.clear(); m_refCount.clear(); } }
void rollback() { m_over.clear(); m_refCount.clear(); }
std::string lookup(h256 _h) const { std::string ret = BasicMap::lookup(_h); if (ret.empty()) m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); return ret; }
std::string lookup(h256 _h) const { std::string ret = BasicMap::lookup(_h); if (ret.empty() && m_db) m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); return ret; }
private:
using BasicMap::clear;
@ -131,7 +131,7 @@ public:
iterator(GenericTrieDB const* _db)
{
m_that = _db;
m_trail.push_back(Node{_db->node(_db->m_root), std::string(1, '\0'), 255}); // one null byte is the HPE for the empty key.
m_trail.push_back({_db->node(_db->m_root), std::string(1, '\0'), 255}); // one null byte is the HPE for the empty key.
next();
}
@ -242,10 +242,13 @@ public:
else
{
// lead-on to another node - enter child.
m_trail.push_back(m_trail.back());
m_trail.back().key = hexPrefixEncode(keyOf(m_trail.back().key), NibbleSlice(bytesConstRef(&m_trail.back().child, 1), 1), false);
m_trail.back().rlp = m_that->deref(rlp[m_trail.back().child]);
m_trail.back().child = 255;
// fixed so that Node passed into push_back is constructed *before* m_trail is potentially resized (which invalidates back and rlp)
Node const& back = m_trail.back();
m_trail.push_back(Node{
m_that->deref(rlp[back.child]),
hexPrefixEncode(keyOf(back.key), NibbleSlice(bytesConstRef(&back.child, 1), 1), false),
255
});
break;
}
}
@ -727,10 +730,10 @@ template <class DB> bytes GenericTrieDB<DB>::cleve(RLP const& _orig, uint _s)
assert(_s && _s <= k.size());
RLPStream bottom(2);
bottom << hexPrefixEncode(k, isLeaf(_orig), _s) << _orig[1];
bottom << hexPrefixEncode(k, isLeaf(_orig), /*ugh*/(int)_s) << _orig[1];
RLPStream top(2);
top << hexPrefixEncode(k, false, 0, _s);
top << hexPrefixEncode(k, false, 0, /*ugh*/(int)_s);
streamNode(top, bottom.out());
return top.out();

14
libethereum/UPnP.cpp

@ -33,8 +33,8 @@ using namespace eth;
UPnP::UPnP()
{
m_urls = new UPNPUrls;
m_data = new IGDdatas;
m_urls.reset(new UPNPUrls);
m_data.reset(new IGDdatas);
m_ok = false;
@ -43,8 +43,8 @@ UPnP::UPnP()
char* descXML;
int descXMLsize = 0;
int upnperror = 0;
memset(m_urls, 0, sizeof(struct UPNPUrls));
memset(m_data, 0, sizeof(struct IGDdatas));
memset(m_urls.get(), 0, sizeof(struct UPNPUrls));
memset(m_data.get(), 0, sizeof(struct IGDdatas));
devlist = upnpDiscover(2000, NULL/*multicast interface*/, NULL/*minissdpd socket path*/, 0/*sameport*/, 0/*ipv6*/, &upnperror);
if (devlist)
{
@ -66,12 +66,12 @@ UPnP::UPnP()
#endif
if (descXML)
{
parserootdesc (descXML, descXMLsize, m_data);
parserootdesc (descXML, descXMLsize, m_data.get());
free (descXML); descXML = 0;
#if MINIUPNPC_API_VERSION >= 9
GetUPNPUrls (m_urls, m_data, dev->descURL, 0);
GetUPNPUrls (m_urls.get(), m_data.get(), dev->descURL, 0);
#else
GetUPNPUrls (m_urls, m_data, dev->descURL);
GetUPNPUrls (m_urls.get(), m_data.get(), dev->descURL);
#endif
m_ok = true;
}

4
libethereum/UPnP.h

@ -45,8 +45,8 @@ public:
std::set<int> m_reg;
bool m_ok;
struct UPNPUrls* m_urls;
struct IGDdatas* m_data;
std::unique_ptr<struct UPNPUrls> m_urls;
std::unique_ptr<struct IGDdatas> m_data;
};
}

60
libethereum/VM.cpp

@ -0,0 +1,60 @@
/*
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 VM.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "VM.h"
#include <secp256k1.h>
#include <boost/filesystem.hpp>
#if WIN32
#pragma warning(push)
#pragma warning(disable:4244)
#else
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
#include <sha.h>
#include <sha3.h>
#include <ripemd.h>
#if WIN32
#pragma warning(pop)
#else
#endif
#include <ctime>
#include <random>
#include "BlockChain.h"
#include "Instruction.h"
#include "Exceptions.h"
#include "Dagger.h"
#include "Defaults.h"
using namespace std;
using namespace eth;
VM::VM()
{
reset();
}
void VM::reset()
{
m_curPC = 0;
m_nextPC = 1;
m_stepCount = 0;
m_runFee = 0;
}

594
libethereum/VM.h

@ -0,0 +1,594 @@
/*
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 VM.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <unordered_map>
#include <secp256k1.h>
#if WIN32
#pragma warning(push)
#pragma warning(disable:4244)
#else
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
#include <sha.h>
#include <sha3.h>
#include <ripemd.h>
#if WIN32
#pragma warning(pop)
#else
#endif
#include "Common.h"
#include "Exceptions.h"
#include "FeeStructure.h"
#include "Instruction.h"
#include "BlockInfo.h"
#include "ExtVMFace.h"
namespace eth
{
// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash.
// Currently we just pull out the right (low-order in BE) 160-bits.
inline Address asAddress(u256 _item)
{
return right160(h256(_item));
}
inline u256 fromAddress(Address _a)
{
return (u160)_a;
}
/**
*/
class VM
{
template <unsigned T> friend class UnitTest;
public:
/// Construct VM object.
VM();
void reset();
template <class Ext>
void go(Ext& _ext, uint64_t _steps = (uint64_t)-1);
void require(u256 _n) { if (m_stack.size() < _n) throw StackTooSmall(_n, m_stack.size()); }
u256 runFee() const { return m_runFee; }
private:
u256 m_curPC = 0;
u256 m_nextPC = 1;
uint64_t m_stepCount = 0;
std::map<u256, u256> m_temp;
std::vector<u256> m_stack;
u256 m_runFee = 0;
};
}
// INLINE:
template <class Ext> void eth::VM::go(Ext& _ext, uint64_t _steps)
{
for (bool stopped = false; !stopped && _steps--; m_curPC = m_nextPC, m_nextPC = m_curPC + 1)
{
m_stepCount++;
// INSTRUCTION...
auto rawInst = _ext.store(m_curPC);
if (rawInst > 0xff)
throw BadInstruction();
Instruction inst = (Instruction)(uint8_t)rawInst;
// FEES...
bigint runFee = m_stepCount > 16 ? _ext.fees.m_stepFee : 0;
bigint storeCostDelta = 0;
switch (inst)
{
case Instruction::SSTORE:
require(2);
if (!_ext.store(m_stack.back()) && m_stack[m_stack.size() - 2])
storeCostDelta += _ext.fees.m_memoryFee;
if (_ext.store(m_stack.back()) && !m_stack[m_stack.size() - 2])
storeCostDelta -= _ext.fees.m_memoryFee;
// continue on to...
case Instruction::SLOAD:
runFee += _ext.fees.m_dataFee;
break;
case Instruction::EXTRO:
case Instruction::BALANCE:
runFee += _ext.fees.m_extroFee;
break;
case Instruction::MKTX:
runFee += _ext.fees.m_txFee;
break;
case Instruction::SHA256:
case Instruction::RIPEMD160:
case Instruction::ECMUL:
case Instruction::ECADD:
case Instruction::ECSIGN:
case Instruction::ECRECOVER:
case Instruction::ECVALID:
runFee += _ext.fees.m_cryptoFee;
break;
default:
break;
}
_ext.payFee(runFee + storeCostDelta);
m_runFee += (u256)runFee;
// EXECUTE...
switch (inst)
{
case Instruction::ADD:
//pops two items and pushes S[-1] + S[-2] mod 2^256.
require(2);
m_stack[m_stack.size() - 2] += m_stack.back();
m_stack.pop_back();
break;
case Instruction::MUL:
//pops two items and pushes S[-1] * S[-2] mod 2^256.
require(2);
m_stack[m_stack.size() - 2] *= m_stack.back();
m_stack.pop_back();
break;
case Instruction::SUB:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() - m_stack[m_stack.size() - 2];
m_stack.pop_back();
break;
case Instruction::DIV:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() / m_stack[m_stack.size() - 2];
m_stack.pop_back();
break;
case Instruction::SDIV:
require(2);
(s256&)m_stack[m_stack.size() - 2] = (s256&)m_stack.back() / (s256&)m_stack[m_stack.size() - 2];
m_stack.pop_back();
break;
case Instruction::MOD:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() % m_stack[m_stack.size() - 2];
m_stack.pop_back();
break;
case Instruction::SMOD:
require(2);
(s256&)m_stack[m_stack.size() - 2] = (s256&)m_stack.back() % (s256&)m_stack[m_stack.size() - 2];
m_stack.pop_back();
break;
case Instruction::EXP:
{
// TODO: better implementation?
require(2);
auto n = m_stack.back();
auto x = m_stack[m_stack.size() - 2];
m_stack.pop_back();
for (u256 i = 0; i < x; ++i)
n *= n;
m_stack.back() = n;
break;
}
case Instruction::NEG:
require(1);
m_stack.back() = ~(m_stack.back() - 1);
break;
case Instruction::LT:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() < m_stack[m_stack.size() - 2] ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::LE:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() <= m_stack[m_stack.size() - 2] ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::GT:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() > m_stack[m_stack.size() - 2] ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::GE:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() >= m_stack[m_stack.size() - 2] ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::EQ:
require(2);
m_stack[m_stack.size() - 2] = m_stack.back() == m_stack[m_stack.size() - 2] ? 1 : 0;
m_stack.pop_back();
break;
case Instruction::NOT:
require(1);
m_stack.back() = m_stack.back() ? 0 : 1;
break;
case Instruction::MYADDRESS:
m_stack.push_back(fromAddress(_ext.myAddress));
break;
case Instruction::TXSENDER:
m_stack.push_back(fromAddress(_ext.txSender));
break;
case Instruction::TXVALUE:
m_stack.push_back(_ext.txValue);
break;
case Instruction::TXDATAN:
m_stack.push_back(_ext.txData.size());
break;
case Instruction::TXDATA:
require(1);
m_stack.back() = m_stack.back() < _ext.txData.size() ? _ext.txData[(uint)m_stack.back()] : 0;
break;
case Instruction::BLK_PREVHASH:
m_stack.push_back(_ext.previousBlock.hash);
break;
case Instruction::BLK_COINBASE:
m_stack.push_back((u160)_ext.currentBlock.coinbaseAddress);
break;
case Instruction::BLK_TIMESTAMP:
m_stack.push_back(_ext.currentBlock.timestamp);
break;
case Instruction::BLK_NUMBER:
m_stack.push_back(_ext.currentNumber);
break;
case Instruction::BLK_DIFFICULTY:
m_stack.push_back(_ext.currentBlock.difficulty);
break;
case Instruction::BLK_NONCE:
m_stack.push_back(_ext.previousBlock.nonce);
break;
case Instruction::BASEFEE:
m_stack.push_back(_ext.fees.multiplier());
break;
case Instruction::SHA256:
{
require(1);
uint s = (uint)std::min(m_stack.back(), (u256)(m_stack.size() - 1) * 32);
m_stack.pop_back();
CryptoPP::SHA256 digest;
uint i = 0;
for (; s; s = (s >= 32 ? s - 32 : 0), i += 32)
{
bytes b = toBigEndian(m_stack.back());
digest.Update(b.data(), (int)std::min<u256>(32, s)); // b.size() == 32
m_stack.pop_back();
}
std::array<byte, 32> final;
digest.TruncatedFinal(final.data(), 32);
m_stack.push_back(fromBigEndian<u256>(final));
break;
}
case Instruction::RIPEMD160:
{
require(1);
uint s = (uint)std::min(m_stack.back(), (u256)(m_stack.size() - 1) * 32);
m_stack.pop_back();
CryptoPP::RIPEMD160 digest;
uint i = 0;
for (; s; s = (s >= 32 ? s - 32 : 0), i += 32)
{
bytes b = toBigEndian(m_stack.back());
digest.Update(b.data(), (int)std::min<u256>(32, s)); // b.size() == 32
m_stack.pop_back();
}
std::array<byte, 20> final;
digest.TruncatedFinal(final.data(), 20);
// NOTE: this aligns to right of 256-bit container (low-order bytes).
// This won't work if they're treated as byte-arrays and thus left-aligned in a 256-bit container.
m_stack.push_back((u256)fromBigEndian<u160>(final));
break;
}
case Instruction::ECMUL:
{
// ECMUL - pops three items.
// If (S[-2],S[-1]) are a valid point in secp256k1, including both coordinates being less than P, pushes (S[-1],S[-2]) * S[-3], using (0,0) as the point at infinity.
// Otherwise, pushes (0,0).
require(3);
bytes pub(1, 4);
pub += toBigEndian(m_stack[m_stack.size() - 2]);
pub += toBigEndian(m_stack.back());
m_stack.pop_back();
m_stack.pop_back();
bytes x = toBigEndian(m_stack.back());
m_stack.pop_back();
if (secp256k1_ecdsa_pubkey_verify(pub.data(), (int)pub.size())) // TODO: Check both are less than P.
{
secp256k1_ecdsa_pubkey_tweak_mul(pub.data(), (int)pub.size(), x.data());
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(1, 32)));
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(33, 32)));
}
else
{
m_stack.push_back(0);
m_stack.push_back(0);
}
break;
}
case Instruction::ECADD:
{
// ECADD - pops four items and pushes (S[-4],S[-3]) + (S[-2],S[-1]) if both points are valid, otherwise (0,0).
require(4);
bytes pub(1, 4);
pub += toBigEndian(m_stack[m_stack.size() - 2]);
pub += toBigEndian(m_stack.back());
m_stack.pop_back();
m_stack.pop_back();
bytes tweak(1, 4);
tweak += toBigEndian(m_stack[m_stack.size() - 2]);
tweak += toBigEndian(m_stack.back());
m_stack.pop_back();
m_stack.pop_back();
if (secp256k1_ecdsa_pubkey_verify(pub.data(),(int) pub.size()) && secp256k1_ecdsa_pubkey_verify(tweak.data(),(int) tweak.size()))
{
secp256k1_ecdsa_pubkey_tweak_add(pub.data(), (int)pub.size(), tweak.data());
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(1, 32)));
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&pub).cropped(33, 32)));
}
else
{
m_stack.push_back(0);
m_stack.push_back(0);
}
break;
}
case Instruction::ECSIGN:
{
require(2);
bytes sig(64);
int v = 0;
u256 msg = m_stack.back();
m_stack.pop_back();
u256 priv = m_stack.back();
m_stack.pop_back();
bytes nonce = toBigEndian(Transaction::kFromMessage(msg, priv));
if (!secp256k1_ecdsa_sign_compact(toBigEndian(msg).data(), 64, sig.data(), toBigEndian(priv).data(), nonce.data(), &v))
throw InvalidSignature();
m_stack.push_back(v + 27);
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&sig).cropped(0, 32)));
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&sig).cropped(32)));
break;
}
case Instruction::ECRECOVER:
{
require(4);
bytes sig = toBigEndian(m_stack[m_stack.size() - 2]) + toBigEndian(m_stack.back());
m_stack.pop_back();
m_stack.pop_back();
int v = (int)m_stack.back();
m_stack.pop_back();
bytes msg = toBigEndian(m_stack.back());
m_stack.pop_back();
byte pubkey[65];
int pubkeylen = 65;
if (secp256k1_ecdsa_recover_compact(msg.data(), (int)msg.size(), sig.data(), pubkey, &pubkeylen, 0, v - 27))
{
m_stack.push_back(0);
m_stack.push_back(0);
}
else
{
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&pubkey[1], 32)));
m_stack.push_back(fromBigEndian<u256>(bytesConstRef(&pubkey[33], 32)));
}
break;
}
case Instruction::ECVALID:
{
require(2);
bytes pub(1, 4);
pub += toBigEndian(m_stack[m_stack.size() - 2]);
pub += toBigEndian(m_stack.back());
m_stack.pop_back();
m_stack.pop_back();
m_stack.back() = secp256k1_ecdsa_pubkey_verify(pub.data(), (int)pub.size()) ? 1 : 0;
break;
}
case Instruction::SHA3:
{
require(1);
uint s = (uint)std::min(m_stack.back(), (u256)(m_stack.size() - 1) * 32);
m_stack.pop_back();
CryptoPP::SHA3_256 digest;
uint i = 0;
for (; s; s = (s >= 32 ? s - 32 : 0), i += 32)
{
bytes b = toBigEndian(m_stack.back());
digest.Update(b.data(), (int)std::min<u256>(32, s)); // b.size() == 32
m_stack.pop_back();
}
std::array<byte, 32> final;
digest.TruncatedFinal(final.data(), 32);
m_stack.push_back(fromBigEndian<u256>(final));
break;
}
case Instruction::PUSH:
{
m_stack.push_back(_ext.store(m_curPC + 1));
m_nextPC = m_curPC + 2;
break;
}
case Instruction::POP:
require(1);
m_stack.pop_back();
break;
case Instruction::DUP:
require(1);
m_stack.push_back(m_stack.back());
break;
/*case Instruction::DUPN:
{
auto s = store(curPC + 1);
if (s == 0 || s > stack.size())
throw OperandOutOfRange(1, stack.size(), s);
stack.push_back(stack[stack.size() - (uint)s]);
nextPC = curPC + 2;
break;
}*/
case Instruction::SWAP:
{
require(2);
auto d = m_stack.back();
m_stack.back() = m_stack[m_stack.size() - 2];
m_stack[m_stack.size() - 2] = d;
break;
}
/*case Instruction::SWAPN:
{
require(1);
auto d = stack.back();
auto s = store(curPC + 1);
if (s == 0 || s > stack.size())
throw OperandOutOfRange(1, stack.size(), s);
stack.back() = stack[stack.size() - (uint)s];
stack[stack.size() - (uint)s] = d;
nextPC = curPC + 2;
break;
}*/
case Instruction::MLOAD:
{
require(1);
#ifdef __clang__
auto mFinder = m_temp.find(m_stack.back());
if (mFinder != m_temp.end())
m_stack.back() = mFinder->second;
else
m_stack.back() = 0;
#else
m_stack.back() = m_temp[m_stack.back()];
#endif
break;
}
case Instruction::MSTORE:
{
require(2);
#ifdef __clang__
auto mFinder = m_temp.find(m_stack.back());
if (mFinder == m_temp.end())
m_temp.insert(std::make_pair(m_stack.back(), m_stack[m_stack.size() - 2]));
else
mFinder->second = m_stack[m_stack.size() - 2];
#else
m_temp[m_stack.back()] = m_stack[m_stack.size() - 2];
#endif
m_stack.pop_back();
m_stack.pop_back();
break;
}
case Instruction::SLOAD:
require(1);
m_stack.back() = _ext.store(m_stack.back());
break;
case Instruction::SSTORE:
require(2);
_ext.setStore(m_stack.back(), m_stack[m_stack.size() - 2]);
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::JMP:
require(1);
m_nextPC = m_stack.back();
m_stack.pop_back();
break;
case Instruction::JMPI:
require(2);
if (m_stack.back())
m_nextPC = m_stack[m_stack.size() - 2];
m_stack.pop_back();
m_stack.pop_back();
break;
case Instruction::IND:
m_stack.push_back(m_curPC);
break;
case Instruction::EXTRO:
{
require(2);
auto memoryAddress = m_stack.back();
m_stack.pop_back();
Address contractAddress = asAddress(m_stack.back());
m_stack.back() = _ext.extro(contractAddress, memoryAddress);
break;
}
case Instruction::BALANCE:
{
require(1);
m_stack.back() = _ext.balance(asAddress(m_stack.back()));
break;
}
case Instruction::MKTX:
{
require(3);
Transaction t;
t.receiveAddress = asAddress(m_stack.back());
m_stack.pop_back();
t.value = m_stack.back();
m_stack.pop_back();
auto itemCount = m_stack.back();
m_stack.pop_back();
if (m_stack.size() < itemCount)
throw OperandOutOfRange(0, m_stack.size(), itemCount);
t.data.reserve((uint)itemCount);
for (auto i = 0; i < itemCount; ++i)
{
t.data.push_back(m_stack.back());
m_stack.pop_back();
}
_ext.mktx(t);
break;
}
case Instruction::SUICIDE:
{
require(1);
Address dest = asAddress(m_stack.back());
_ext.suicide(dest);
// ...follow through to...
}
case Instruction::STOP:
return;
default:
throw BadInstruction();
}
}
if (_steps == (unsigned)-1)
throw StepsDone();
}

14
release.sh

@ -1,7 +1,12 @@
#!/bin/bash
dist="saucy"
version=$1
version=$(grep "define ETH_VERSION" libethereum/Common.h | cut -d ' ' -f 3)
branch="$(git branch | grep \* | cut -c 3-)"
if [[ ! "$1" == "" ]]; then
version=$1
fi
if [[ ! "$3" == "" ]]; then
if [[ ! "$4" == "" ]]; then
@ -25,12 +30,9 @@ cd /tmp
echo Checking out...
git clone $opwd
cd cpp-ethereum
git checkout "$branch"
if [ "$1" == "" ]; then
archdir="cpp-ethereum-$(date +%Y%m%d)"
else
archdir="cpp-ethereum-$version"
fi
archdir="cpp-ethereum-$version"
archfile="$archdir.tar.bz2"
echo Cleaning backup files...

2
secp256k1/impl/num.h

@ -11,6 +11,8 @@
#include "num_gmp.h"
#elif defined(USE_NUM_OPENSSL)
#include "num_openssl.h"
#elif defined(USE_NUM_BOOST)
#include "num_boost.h"
#else
#error "Please select num implementation"
#endif

212
secp256k1/impl/num_boost.h

@ -0,0 +1,212 @@
// Copyright (c) 2014 Tim Hughes
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _SECP256K1_NUM_REPR_IMPL_H_
#define _SECP256K1_NUM_REPR_IMPL_H_
#include <assert.h>
#include <boost/math/common_factor.hpp>
void static secp256k1_num_init(secp256k1_num_t *r)
{
*r = 0;
}
void static secp256k1_num_free(secp256k1_num_t*)
{
}
void static secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a)
{
*r = *a;
}
int static secp256k1_num_bits(const secp256k1_num_t *a)
{
int numLimbs = a->backend().size();
int ret = (numLimbs - 1) * a->backend().limb_bits;
for (auto x = a->backend().limbs()[numLimbs - 1]; x; x >>= 1, ++ret);
return ret;
}
void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a)
{
for (auto n = abs(*a); n; n >>= 8)
{
assert(rlen > 0); // out of space?
r[--rlen] = n.convert_to<unsigned char>();
}
memset(r, 0, rlen);
}
void static secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen)
{
*r = 0;
for (unsigned int i = 0; i != alen; ++i)
{
*r <<= 8;
*r |= a[i];
}
}
void static secp256k1_num_set_int(secp256k1_num_t *r, int a)
{
*r = a;
}
void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m)
{
*r %= *m;
}
void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *n, const secp256k1_num_t *m)
{
// http://rosettacode.org/wiki/Modular_inverse
secp256k1_num_t a = *n;
secp256k1_num_t b = *m;
secp256k1_num_t x0 = 0;
secp256k1_num_t x1 = 1;
assert(*n > 0);
assert(*m > 0);
if (b != 1)
{
secp256k1_num_t q, t;
while (a > 1)
{
boost::multiprecision::divide_qr(a, b, q, t);
a = b; b = t;
t = x1 - q * x0;
x1 = x0; x0 = t;
}
if (x1 < 0)
{
x1 += *m;
}
}
*r = x1;
// check result
#ifdef _DEBUG
{
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>> bignum;
bignum br = *r, bn = *n, bm = *m;
assert((((bn) * (br)) % bm) == 1);
}
#endif
}
int static secp256k1_num_is_zero(const secp256k1_num_t *a)
{
return a->is_zero();
}
int static secp256k1_num_is_odd(const secp256k1_num_t *a)
{
return boost::multiprecision::bit_test(*a, 0);
}
int static secp256k1_num_is_neg(const secp256k1_num_t *a)
{
return a->backend().isneg();
}
int static secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b)
{
return a->backend().compare_unsigned(b->backend());
}
void static secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b)
{
*r = (*a) + (*b);
}
void static secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b)
{
*r = (*a) - (*b);
}
void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b)
{
*r = (*a) * (*b);
}
void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b)
{
*r = (*a) / (*b);
}
void static secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, const secp256k1_num_t *m)
{
secp256k1_num_mul(r, a, b);
secp256k1_num_mod(r, m);
}
int static secp256k1_num_shift(secp256k1_num_t *r, int bits)
{
unsigned ret = r->convert_to<unsigned>() & ((1 << bits) - 1);
*r >>= bits;
return ret;
}
int static secp256k1_num_get_bit(const secp256k1_num_t *a, int pos)
{
return boost::multiprecision::bit_test(*a, pos);
}
void static secp256k1_num_inc(secp256k1_num_t *r)
{
++*r;
}
void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen)
{
static const unsigned char cvt[256] = {
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0,
0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0
};
*r = 0;
for (int i = 0; i != alen; ++i)
{
*r <<= 4;
*r |= cvt[a[i]];
}
}
void static secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a)
{
static const unsigned char cvt[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for (auto n = *a; n; n >>= 4)
{
assert(rlen > 0); // out of space?
r[--rlen] = cvt[n.convert_to<unsigned char>() & 15];
}
memset(r, '0', rlen);
}
void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits)
{
*rl = *a & ((secp256k1_num_t(1) << bits) - 1);
*rh = *a >> bits;
}
void static secp256k1_num_negate(secp256k1_num_t *r)
{
r->backend().negate();
}
#endif

2
secp256k1/num.h

@ -9,6 +9,8 @@
#include "num_gmp.h"
#elif defined(USE_NUM_OPENSSL)
#include "num_openssl.h"
#elif defined(USE_NUM_BOOST)
#include "num_boost.h"
#else
#error "Please select num implementation"
#endif

12
secp256k1/num_boost.h

@ -0,0 +1,12 @@
// Copyright (c) 2013 Pieter Wuille
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _SECP256K1_NUM_REPR_
#define _SECP256K1_NUM_REPR_
#include <boost/multiprecision/cpp_int.hpp>
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>> secp256k1_num_t ;
#endif

8
secp256k1/secp256k1.c

@ -8,6 +8,10 @@
#include "impl/ecmult.h"
#include "impl/ecdsa.h"
#ifdef __cplusplus
extern "C" {
#endif
void secp256k1_start(void) {
secp256k1_fe_start();
secp256k1_ge_start();
@ -267,3 +271,7 @@ int secp256k1_ecdsa_privkey_import(unsigned char *seckey, const unsigned char *p
secp256k1_num_free(&key);
return ret;
}
#ifdef __cplusplus
}
#endif

470
secp256k1/tests.c

@ -0,0 +1,470 @@
// Copyright (c) 2013 Pieter Wuille
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined HAVE_CONFIG_H
#include "libsecp256k1-config.h"
#endif
#include <assert.h>
#include <stdio.h>
#include "impl/num.h"
#include "impl/field.h"
#include "impl/group.h"
#include "impl/ecmult.h"
#include "impl/ecdsa.h"
#include "impl/util.h"
#ifdef ENABLE_OPENSSL_TESTS
#include "openssl/bn.h"
#include "openssl/ec.h"
#include "openssl/ecdsa.h"
#include "openssl/obj_mac.h"
#endif
static int count = 100;
/***** NUM TESTS *****/
void random_num_negate(secp256k1_num_t *num) {
if (secp256k1_rand32() & 1)
secp256k1_num_negate(num);
}
void random_num_order_test(secp256k1_num_t *num) {
do {
unsigned char b32[32];
secp256k1_rand256_test(b32);
secp256k1_num_set_bin(num, b32, 32);
if (secp256k1_num_is_zero(num))
continue;
if (secp256k1_num_cmp(num, &secp256k1_ge_consts->order) >= 0)
continue;
break;
} while(1);
}
void random_num_order(secp256k1_num_t *num) {
do {
unsigned char b32[32];
secp256k1_rand256(b32);
secp256k1_num_set_bin(num, b32, 32);
if (secp256k1_num_is_zero(num))
continue;
if (secp256k1_num_cmp(num, &secp256k1_ge_consts->order) >= 0)
continue;
break;
} while(1);
}
void test_num_copy_inc_cmp() {
secp256k1_num_t n1,n2;
secp256k1_num_init(&n1);
secp256k1_num_init(&n2);
random_num_order(&n1);
secp256k1_num_copy(&n2, &n1);
assert(secp256k1_num_cmp(&n1, &n2) == 0);
assert(secp256k1_num_cmp(&n2, &n1) == 0);
secp256k1_num_inc(&n2);
assert(secp256k1_num_cmp(&n1, &n2) != 0);
assert(secp256k1_num_cmp(&n2, &n1) != 0);
secp256k1_num_free(&n1);
secp256k1_num_free(&n2);
}
void test_num_get_set_hex() {
secp256k1_num_t n1,n2;
secp256k1_num_init(&n1);
secp256k1_num_init(&n2);
random_num_order_test(&n1);
char c[64];
secp256k1_num_get_hex(c, 64, &n1);
secp256k1_num_set_hex(&n2, c, 64);
assert(secp256k1_num_cmp(&n1, &n2) == 0);
for (int i=0; i<64; i++) {
// check whether the lower 4 bits correspond to the last hex character
int low1 = secp256k1_num_shift(&n1, 4);
int lowh = c[63];
int low2 = (lowh>>6)*9+(lowh-'0')&15;
assert(low1 == low2);
// shift bits off the hex representation, and compare
memmove(c+1, c, 63);
c[0] = '0';
secp256k1_num_set_hex(&n2, c, 64);
assert(secp256k1_num_cmp(&n1, &n2) == 0);
}
secp256k1_num_free(&n2);
secp256k1_num_free(&n1);
}
void test_num_get_set_bin() {
secp256k1_num_t n1,n2;
secp256k1_num_init(&n1);
secp256k1_num_init(&n2);
random_num_order_test(&n1);
unsigned char c[32];
secp256k1_num_get_bin(c, 32, &n1);
secp256k1_num_set_bin(&n2, c, 32);
assert(secp256k1_num_cmp(&n1, &n2) == 0);
for (int i=0; i<32; i++) {
// check whether the lower 8 bits correspond to the last byte
int low1 = secp256k1_num_shift(&n1, 8);
int low2 = c[31];
assert(low1 == low2);
// shift bits off the byte representation, and compare
memmove(c+1, c, 31);
c[0] = 0;
secp256k1_num_set_bin(&n2, c, 32);
assert(secp256k1_num_cmp(&n1, &n2) == 0);
}
secp256k1_num_free(&n2);
secp256k1_num_free(&n1);
}
void run_num_int() {
secp256k1_num_t n1;
secp256k1_num_init(&n1);
for (int i=-255; i<256; i++) {
unsigned char c1[3] = {};
c1[2] = abs(i);
unsigned char c2[3] = {0x11,0x22,0x33};
secp256k1_num_set_int(&n1, i);
secp256k1_num_get_bin(c2, 3, &n1);
assert(memcmp(c1, c2, 3) == 0);
}
secp256k1_num_free(&n1);
}
void test_num_negate() {
secp256k1_num_t n1;
secp256k1_num_t n2;
secp256k1_num_init(&n1);
secp256k1_num_init(&n2);
random_num_order_test(&n1); // n1 = R
random_num_negate(&n1);
secp256k1_num_copy(&n2, &n1); // n2 = R
secp256k1_num_sub(&n1, &n2, &n1); // n1 = n2-n1 = 0
assert(secp256k1_num_is_zero(&n1));
secp256k1_num_copy(&n1, &n2); // n1 = R
secp256k1_num_negate(&n1); // n1 = -R
assert(!secp256k1_num_is_zero(&n1));
secp256k1_num_add(&n1, &n2, &n1); // n1 = n2+n1 = 0
assert(secp256k1_num_is_zero(&n1));
secp256k1_num_copy(&n1, &n2); // n1 = R
secp256k1_num_negate(&n1); // n1 = -R
assert(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2));
secp256k1_num_negate(&n1); // n1 = R
assert(secp256k1_num_cmp(&n1, &n2) == 0);
assert(secp256k1_num_is_neg(&n1) == secp256k1_num_is_neg(&n2));
secp256k1_num_free(&n2);
secp256k1_num_free(&n1);
}
void test_num_add_sub() {
secp256k1_num_t n1;
secp256k1_num_t n2;
secp256k1_num_init(&n1);
secp256k1_num_init(&n2);
random_num_order_test(&n1); // n1 = R1
random_num_negate(&n1);
random_num_order_test(&n2); // n2 = R2
random_num_negate(&n2);
secp256k1_num_t n1p2, n2p1, n1m2, n2m1;
secp256k1_num_init(&n1p2);
secp256k1_num_init(&n2p1);
secp256k1_num_init(&n1m2);
secp256k1_num_init(&n2m1);
secp256k1_num_add(&n1p2, &n1, &n2); // n1p2 = R1 + R2
secp256k1_num_add(&n2p1, &n2, &n1); // n2p1 = R2 + R1
secp256k1_num_sub(&n1m2, &n1, &n2); // n1m2 = R1 - R2
secp256k1_num_sub(&n2m1, &n2, &n1); // n2m1 = R2 - R1
assert(secp256k1_num_cmp(&n1p2, &n2p1) == 0);
assert(secp256k1_num_cmp(&n1p2, &n1m2) != 0);
secp256k1_num_negate(&n2m1); // n2m1 = -R2 + R1
assert(secp256k1_num_cmp(&n2m1, &n1m2) == 0);
assert(secp256k1_num_cmp(&n2m1, &n1) != 0);
secp256k1_num_add(&n2m1, &n2m1, &n2); // n2m1 = -R2 + R1 + R2 = R1
assert(secp256k1_num_cmp(&n2m1, &n1) == 0);
assert(secp256k1_num_cmp(&n2p1, &n1) != 0);
secp256k1_num_sub(&n2p1, &n2p1, &n2); // n2p1 = R2 + R1 - R2 = R1
assert(secp256k1_num_cmp(&n2p1, &n1) == 0);
secp256k1_num_free(&n2m1);
secp256k1_num_free(&n1m2);
secp256k1_num_free(&n2p1);
secp256k1_num_free(&n1p2);
secp256k1_num_free(&n2);
secp256k1_num_free(&n1);
}
void run_num_smalltests() {
for (int i=0; i<100*count; i++) {
test_num_copy_inc_cmp();
test_num_get_set_hex();
test_num_get_set_bin();
test_num_negate();
test_num_add_sub();
}
run_num_int();
}
void run_ecmult_chain() {
// random starting point A (on the curve)
secp256k1_fe_t ax; secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64);
secp256k1_fe_t ay; secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64);
secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
// two random initial factors xn and gn
secp256k1_num_t xn;
secp256k1_num_init(&xn);
secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64);
secp256k1_num_t gn;
secp256k1_num_init(&gn);
secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64);
// two small multipliers to be applied to xn and gn in every iteration:
secp256k1_num_t xf;
secp256k1_num_init(&xf);
secp256k1_num_set_hex(&xf, "1337", 4);
secp256k1_num_t gf;
secp256k1_num_init(&gf);
secp256k1_num_set_hex(&gf, "7113", 4);
// accumulators with the resulting coefficients to A and G
secp256k1_num_t ae;
secp256k1_num_init(&ae);
secp256k1_num_set_int(&ae, 1);
secp256k1_num_t ge;
secp256k1_num_init(&ge);
secp256k1_num_set_int(&ge, 0);
// the point being computed
secp256k1_gej_t x = a;
const secp256k1_num_t *order = &secp256k1_ge_consts->order;
for (int i=0; i<200*count; i++) {
// in each iteration, compute X = xn*X + gn*G;
secp256k1_ecmult(&x, &x, &xn, &gn);
// also compute ae and ge: the actual accumulated factors for A and G
// if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G)
secp256k1_num_mod_mul(&ae, &ae, &xn, order);
secp256k1_num_mod_mul(&ge, &ge, &xn, order);
secp256k1_num_add(&ge, &ge, &gn);
secp256k1_num_mod(&ge, order);
// modify xn and gn
secp256k1_num_mod_mul(&xn, &xn, &xf, order);
secp256k1_num_mod_mul(&gn, &gn, &gf, order);
// verify
if (i == 19999) {
char res[132]; int resl = 132;
secp256k1_gej_get_hex(res, &resl, &x);
assert(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0);
}
}
// redo the computation, but directly with the resulting ae and ge coefficients:
secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge);
char res[132]; int resl = 132;
char res2[132]; int resl2 = 132;
secp256k1_gej_get_hex(res, &resl, &x);
secp256k1_gej_get_hex(res2, &resl2, &x2);
assert(strcmp(res, res2) == 0);
assert(strlen(res) == 131);
secp256k1_num_free(&xn);
secp256k1_num_free(&gn);
secp256k1_num_free(&xf);
secp256k1_num_free(&gf);
secp256k1_num_free(&ae);
secp256k1_num_free(&ge);
}
void test_point_times_order(const secp256k1_gej_t *point) {
// either the point is not on the curve, or multiplying it by the order results in O
if (!secp256k1_gej_is_valid(point))
return;
const secp256k1_num_t *order = &secp256k1_ge_consts->order;
secp256k1_num_t zero;
secp256k1_num_init(&zero);
secp256k1_num_set_int(&zero, 0);
secp256k1_gej_t res;
secp256k1_ecmult(&res, point, order, order); // calc res = order * point + order * G;
assert(secp256k1_gej_is_infinity(&res));
secp256k1_num_free(&zero);
}
void run_point_times_order() {
secp256k1_fe_t x; secp256k1_fe_set_hex(&x, "02", 2);
for (int i=0; i<500; i++) {
secp256k1_ge_t p; secp256k1_ge_set_xo(&p, &x, 1);
secp256k1_gej_t j; secp256k1_gej_set_ge(&j, &p);
test_point_times_order(&j);
secp256k1_fe_sqr(&x, &x);
}
char c[65]; int cl=65;
secp256k1_fe_get_hex(c, &cl, &x);
assert(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0);
}
void test_wnaf(const secp256k1_num_t *number, int w) {
secp256k1_num_t x, two, t;
secp256k1_num_init(&x);
secp256k1_num_init(&two);
secp256k1_num_init(&t);
secp256k1_num_set_int(&x, 0);
secp256k1_num_set_int(&two, 2);
int wnaf[257];
int bits = secp256k1_ecmult_wnaf(wnaf, number, w);
int zeroes = -1;
for (int i=bits-1; i>=0; i--) {
secp256k1_num_mul(&x, &x, &two);
int v = wnaf[i];
if (v) {
assert(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1
zeroes=0;
assert((v & 1) == 1); // check non-zero elements are odd
assert(v <= (1 << (w-1)) - 1); // check range below
assert(v >= -(1 << (w-1)) - 1); // check range above
} else {
assert(zeroes != -1); // check that no unnecessary zero padding exists
zeroes++;
}
secp256k1_num_set_int(&t, v);
secp256k1_num_add(&x, &x, &t);
}
assert(secp256k1_num_cmp(&x, number) == 0); // check that wnaf represents number
secp256k1_num_free(&x);
secp256k1_num_free(&two);
secp256k1_num_free(&t);
}
void run_wnaf() {
secp256k1_num_t n;
secp256k1_num_init(&n);
for (int i=0; i<count; i++) {
random_num_order(&n);
if (i % 1)
secp256k1_num_negate(&n);
test_wnaf(&n, 4+(i%10));
}
secp256k1_num_free(&n);
}
void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *key, const secp256k1_num_t *msg, int *recid) {
secp256k1_num_t nonce;
secp256k1_num_init(&nonce);
do {
random_num_order_test(&nonce);
} while(!secp256k1_ecdsa_sig_sign(sig, key, msg, &nonce, recid));
secp256k1_num_free(&nonce);
}
void test_ecdsa_sign_verify() {
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
secp256k1_num_t msg, key;
secp256k1_num_init(&msg);
random_num_order_test(&msg);
secp256k1_num_init(&key);
random_num_order_test(&key);
secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key);
secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj);
secp256k1_ecdsa_sig_t sig;
secp256k1_ecdsa_sig_init(&sig);
random_sign(&sig, &key, &msg, NULL);
assert(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
secp256k1_num_inc(&msg);
assert(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
secp256k1_ecdsa_sig_free(&sig);
secp256k1_num_free(&msg);
secp256k1_num_free(&key);
}
void run_ecdsa_sign_verify() {
for (int i=0; i<10*count; i++) {
test_ecdsa_sign_verify();
}
}
#ifdef ENABLE_OPENSSL_TESTS
EC_KEY *get_openssl_key(const secp256k1_num_t *key) {
unsigned char privkey[300];
int privkeylen;
int compr = secp256k1_rand32() & 1;
const unsigned char* pbegin = privkey;
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
assert(secp256k1_ecdsa_privkey_serialize(privkey, &privkeylen, key, compr));
assert(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
assert(EC_KEY_check_key(ec_key));
return ec_key;
}
void test_ecdsa_openssl() {
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
secp256k1_num_t key, msg;
secp256k1_num_init(&msg);
unsigned char message[32];
secp256k1_rand256_test(message);
secp256k1_num_set_bin(&msg, message, 32);
secp256k1_num_init(&key);
random_num_order_test(&key);
secp256k1_gej_t qj;
secp256k1_ecmult_gen(&qj, &key);
secp256k1_ge_t q;
secp256k1_ge_set_gej(&q, &qj);
EC_KEY *ec_key = get_openssl_key(&key);
assert(ec_key);
unsigned char signature[80];
int sigsize = 80;
assert(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
secp256k1_ecdsa_sig_t sig;
secp256k1_ecdsa_sig_init(&sig);
assert(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
assert(secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
secp256k1_num_inc(&sig.r);
assert(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
random_sign(&sig, &key, &msg, NULL);
sigsize = 80;
assert(secp256k1_ecdsa_sig_serialize(signature, &sigsize, &sig));
assert(ECDSA_verify(0, message, sizeof(message), signature, sigsize, ec_key) == 1);
secp256k1_ecdsa_sig_free(&sig);
EC_KEY_free(ec_key);
secp256k1_num_free(&key);
secp256k1_num_free(&msg);
}
void run_ecdsa_openssl() {
for (int i=0; i<10*count; i++) {
test_ecdsa_openssl();
}
}
#endif
int main(int argc, char **argv) {
if (argc > 1)
count = strtol(argv[1], NULL, 0)*47;
printf("test count = %i\n", count);
// initialize
secp256k1_fe_start();
secp256k1_ge_start();
secp256k1_ecmult_start();
// num tests
run_num_smalltests();
// ecmult tests
run_wnaf();
run_point_times_order();
run_ecmult_chain();
// ecdsa tests
run_ecdsa_sign_verify();
#ifdef ENABLE_OPENSSL_TESTS
run_ecdsa_openssl();
#endif
// shutdown
secp256k1_ecmult_stop();
secp256k1_ge_stop();
secp256k1_fe_stop();
return 0;
}

8
test/crypto.cpp

@ -87,7 +87,7 @@ int cryptoTest()
ret = secp256k1_ecdsa_pubkey_create(pubkey.data(), &pubkeylen, privkey.data(), 1);
pubkey.resize(pubkeylen);
int good = secp256k1_ecdsa_pubkey_verify(pubkey.data(), pubkey.size());
int good = secp256k1_ecdsa_pubkey_verify(pubkey.data(), (int)pubkey.size());
cout << "PUB: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << (good ? " GOOD" : " BAD") << endl;
}
@ -99,12 +99,12 @@ int cryptoTest()
cout << asHex(hmsg) << endl;
cout << asHex(privkey) << endl;
cout << hex << nonce << dec << endl;
int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v);
int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), (int)hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v);
cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << asHex(sig) << " " << v << endl;
bytes pubkey(65);
int pubkeylen = 65;
ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), hmsg.size(), (byte const*)sig.data(), pubkey.data(), &pubkeylen, 0, v);
ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), (int)hmsg.size(), (byte const*)sig.data(), pubkey.data(), &pubkeylen, 0, v);
pubkey.resize(pubkeylen);
cout << "MYREC: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << endl;
}
@ -112,7 +112,7 @@ int cryptoTest()
{
bytes pubkey(65);
int pubkeylen = 65;
int ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), hmsg.size(), (byte const*)sig64.data(), pubkey.data(), &pubkeylen, 0, (int)t.vrs.v - 27);
int ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), (int)hmsg.size(), (byte const*)sig64.data(), pubkey.data(), &pubkeylen, 0, (int)t.vrs.v - 27);
pubkey.resize(pubkeylen);
cout << "RECPUB: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << endl;
cout << "SENDER: " << hex << low160(eth::sha3(bytesConstRef(&pubkey).cropped(1))) << dec << endl;

10
test/dagger.cpp

@ -30,19 +30,17 @@ int daggerTest()
{
// Test dagger
{
Dagger d;
auto s = steady_clock::now();
cout << hex << d.eval((h256)1, (h256)0);
cout << hex << Dagger().eval((h256)(u256)1, (h256)(u256)0);
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl;
cout << hex << d.eval((h256)1, (h256)1);
cout << hex << Dagger().eval((h256)(u256)1, (h256)(u256)1);
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl;
}
{
Dagger d;
auto s = steady_clock::now();
cout << hex << d.eval((h256)1, (h256)0);
cout << hex << Dagger().eval((h256)(u256)1, (h256)(u256)0);
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl;
cout << hex << d.eval((h256)1, (h256)1);
cout << hex << Dagger().eval((h256)(u256)1, (h256)(u256)1);
cout << " " << dec << duration_cast<milliseconds>(steady_clock::now() - s).count() << " ms" << endl;
}
return 0;

4
test/main.cpp

@ -27,13 +27,14 @@ int rlpTest();
int daggerTest();
int cryptoTest();
int stateTest();
int vmTest();
int hexPrefixTest();
int peerTest(int argc, char** argv);
#include <BlockInfo.h>
using namespace eth;
int main(int argc, char** argv)
int main(int, char**)
{
/* RLPStream s;
BlockInfo::genesis().fillStream(s, false);
@ -46,6 +47,7 @@ int main(int argc, char** argv)
trieTest();
daggerTest();
cryptoTest();
vmTest();
// stateTest();
// peerTest(argc, argv);
return 0;

7
test/peer.cpp

@ -22,6 +22,7 @@
#include <chrono>
#include <thread>
#include <boost/filesystem/operations.hpp>
#include <BlockChain.h>
#include <PeerNetwork.h>
using namespace std;
@ -38,16 +39,16 @@ int peerTest(int argc, char** argv)
{
string arg = argv[i];
if (arg == "-l" && i + 1 < argc)
listenPort = atoi(argv[++i]);
listenPort = (short)atoi(argv[++i]);
else if (arg == "-r" && i + 1 < argc)
remoteHost = argv[++i];
else if (arg == "-p" && i + 1 < argc)
remotePort = atoi(argv[++i]);
remotePort = (short)atoi(argv[++i]);
else
remoteHost = argv[i];
}
BlockChain ch("/tmp");
BlockChain ch(boost::filesystem::temp_directory_path().string());
PeerServer pn("Test", ch, 0, listenPort);
if (!remoteHost.empty())

3
test/state.cpp

@ -20,6 +20,7 @@
* State test functions.
*/
#include <boost/filesystem/operations.hpp>
#include <secp256k1.h>
#include <BlockChain.h>
#include <State.h>
@ -33,7 +34,7 @@ int stateTest()
KeyPair myMiner = sha3("Gav's Miner");
// KeyPair you = sha3("123");
Defaults::setDBPath("/tmp");
Defaults::setDBPath(boost::filesystem::temp_directory_path().string());
Overlay stateDB = State::openDB();
BlockChain bc;

15
test/trie.cpp

@ -27,6 +27,11 @@
using namespace std;
using namespace eth;
inline h256 stringMapHash256(StringMap const& _s)
{
return hash256(_s);
}
int trieTest()
{
{
@ -42,13 +47,13 @@ int trieTest()
cout << t;
cout << m;
cout << t.root() << endl;
cout << hash256({{"test", "test"}}) << endl;
cout << stringMapHash256({{"test", "test"}}) << endl;
t.insert(string("tesa"), string("testy"));
cout << t;
cout << m;
cout << t.root() << endl;
cout << hash256({{"test", "test"}, {"te", "testy"}}) << endl;
cout << stringMapHash256({{"test", "test"}, {"te", "testy"}}) << endl;
cout << t.at(string("test")) << endl;
cout << t.at(string("te")) << endl;
cout << t.at(string("t")) << endl;
@ -56,7 +61,7 @@ int trieTest()
t.remove(string("te"));
cout << m;
cout << t.root() << endl;
cout << hash256({{"test", "test"}}) << endl;
cout << stringMapHash256({{"test", "test"}}) << endl;
t.remove(string("test"));
cout << m;
@ -72,7 +77,7 @@ int trieTest()
cout << t;
cout << m;
cout << t.root() << endl;
cout << hash256({{"b", "B"}, {"a", "A"}}) << endl;
cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl;
cout << RLP(rlp256({{"b", "B"}, {"a", "A"}})) << endl;
}
{
@ -89,7 +94,7 @@ int trieTest()
cout << RLP(t.rlp()) << endl;
}
{
cout << hex << hash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl;
cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl;
MemTrie t;
t.insert("dog", "puppy");
t.insert("doe", "reindeer");

451
test/vm.cpp

@ -0,0 +1,451 @@
/*
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 state.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
* State test functions.
*/
#include <fstream>
#include "../json_spirit/json_spirit_reader_template.h"
#include "../json_spirit/json_spirit_writer_template.h"
#include <ExtVMFace.h>
#include <Transaction.h>
#include <VM.h>
#include <Instruction.h>
using namespace std;
using namespace json_spirit;
using namespace eth;
namespace eth
{
class FakeExtVM: public ExtVMFace
{
public:
FakeExtVM()
{}
FakeExtVM(FeeStructure const& _fees, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, uint _currentNumber):
ExtVMFace(Address(), Address(), 0, u256s(), _fees, _previousBlock, _currentBlock, _currentNumber)
{}
u256 store(u256 _n)
{
#ifdef __clang__
tuple<u256, u256, u256, map<u256, u256> > & address = addresses[myAddress];
map<u256, u256> & third = get<3>(address);
auto sFinder = third.find(_n);
if (sFinder != third.end())
return sFinder->second;
else
return 0;
#else
return get<3>(addresses[myAddress])[_n];
#endif
}
void setStore(u256 _n, u256 _v)
{
#ifdef __clang__
tuple<u256, u256, u256, map<u256, u256> > & address = addresses[myAddress];
map<u256, u256> & third = get<3>(address);
auto sFinder = third.find(_n);
if (sFinder != third.end())
sFinder->second = _v;
else
third.insert(std::make_pair(_n, _v));
#else
get<3>(addresses[myAddress])[_n] = _v;
#endif
}
void mktx(Transaction& _t)
{
if (get<0>(addresses[myAddress]) >= _t.value)
{
get<0>(addresses[myAddress]) -= _t.value;
get<1>(addresses[myAddress])++;
// get<0>(addresses[_t.receiveAddress]) += _t.value;
txs.push_back(_t);
}
}
u256 balance(Address _a) { return get<0>(addresses[_a]); }
void payFee(bigint _fee) { get<0>(addresses[myAddress]) = (u256)(get<0>(addresses[myAddress]) - _fee); }
u256 txCount(Address _a) { return get<1>(addresses[_a]); }
u256 extro(Address _a, u256 _pos)
{
#ifdef __clang__
tuple<u256, u256, u256, map<u256, u256> > & address = addresses[_a];
map<u256, u256> & third = get<3>(address);
auto sFinder = third.find(_pos);
if (sFinder != third.end())
return sFinder->second;
else
return 0;
#else
return get<3>(addresses[_a])[_pos];
#endif
}
u256 extroPrice(Address _a) { return get<2>(addresses[_a]); }
void suicide(Address _a)
{
for (auto const& i: get<3>(addresses[myAddress]))
if (i.second)
get<0>(addresses[_a]) += fees.m_memoryFee;
get<0>(addresses[_a]) += get<0>(addresses[myAddress]);
addresses.erase(myAddress);
}
void setTransaction(Address _txSender, u256 _txValue, u256s const& _txData)
{
txSender = _txSender;
txValue = _txValue;
txData = _txData;
}
void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, u256s _myData)
{
myAddress = _myAddress;
set(myAddress, _myBalance, _myNonce, _myData);
}
void set(Address _a, u256 _myBalance, u256 _myNonce, u256s _myData)
{
get<0>(addresses[_a]) = _myBalance;
get<1>(addresses[_a]) = _myNonce;
get<2>(addresses[_a]) = 0;
for (unsigned i = 0; i < _myData.size(); ++i)
#ifdef __clang__
{
tuple<u256, u256, u256, map<u256, u256> > & address = addresses[_a];
map<u256, u256> & third = get<3>(address);
auto sFinder = third.find(i);
if (sFinder != third.end())
sFinder->second = _myData[i];
else
third.insert(std::make_pair(i, _myData[i]));
}
#else
get<3>(addresses[_a])[i] = _myData[i];
#endif
}
mObject exportEnv()
{
mObject ret;
ret["previousHash"] = toString(previousBlock.hash);
ret["previousNonce"] = toString(previousBlock.nonce);
push(ret, "currentDifficulty", currentBlock.difficulty);
push(ret, "currentTimestamp", currentBlock.timestamp);
ret["currentCoinbase"] = toString(currentBlock.coinbaseAddress);
push(ret, "feeMultiplier", fees.multiplier());
return ret;
}
void importEnv(mObject& _o)
{
previousBlock.hash = h256(_o["previousHash"].get_str());
previousBlock.nonce = h256(_o["previousNonce"].get_str());
currentBlock.difficulty = toInt(_o["currentDifficulty"]);
currentBlock.timestamp = toInt(_o["currentTimestamp"]);
currentBlock.coinbaseAddress = Address(_o["currentCoinbase"].get_str());
fees.setMultiplier(toInt(_o["feeMultiplier"]));
}
static u256 toInt(mValue const& _v)
{
switch (_v.type())
{
case str_type: return u256(_v.get_str());
case int_type: return (u256)_v.get_uint64();
case bool_type: return (u256)(uint64_t)_v.get_bool();
case real_type: return (u256)(uint64_t)_v.get_real();
default: cwarn << "Bad type for scalar: " << _v.type();
}
return 0;
}
static void push(mObject& o, string const& _n, u256 _v)
{
if (_v < (u256)1 << 64)
o[_n] = (uint64_t)_v;
else
o[_n] = toString(_v);
}
static void push(mArray& a, u256 _v)
{
if (_v < (u256)1 << 64)
a.push_back((uint64_t)_v);
else
a.push_back(toString(_v));
}
mObject exportState()
{
mObject ret;
for (auto const& a: addresses)
{
mObject o;
push(o, "balance", get<0>(a.second));
push(o, "nonce", get<1>(a.second));
push(o, "extroPrice", get<2>(a.second));
mObject store;
string curKey;
u256 li = 0;
mArray curVal;
for (auto const& s: get<3>(a.second))
{
if (!li || s.first > li + 8)
{
if (li)
store[curKey] = curVal;
li = s.first;
curKey = toString(li);
curVal = mArray();
}
else
for (; li != s.first; ++li)
curVal.push_back(0);
push(curVal, s.second);
++li;
}
if (li)
{
store[curKey] = curVal;
o["store"] = store;
}
ret[toString(a.first)] = o;
}
return ret;
}
void importState(mObject& _o)
{
for (auto const& i: _o)
{
mObject o = i.second.get_obj();
auto& a = addresses[Address(i.first)];
get<0>(a) = toInt(o["balance"]);
get<1>(a) = toInt(o["nonce"]);
get<2>(a) = toInt(o["extroPrice"]);
if (o.count("store"))
for (auto const& j: o["store"].get_obj())
{
u256 adr(j.first);
for (auto const& k: j.second.get_array())
#ifdef __clang__
{
map<u256, u256> & third = get<3>(a);
auto sFinder = third.find(adr);
if (sFinder != third.end())
sFinder->second = toInt(k);
else
third.insert(std::make_pair(adr, toInt(k)));
adr++;
}
#else
get<3>(a)[adr++] = toInt(k);
#endif
}
if (o.count("code"))
{
u256s d = compileLisp(o["code"].get_str());
for (unsigned i = 0; i < d.size(); ++i)
#ifdef __clang__
{
map<u256, u256> & third = get<3>(a);
auto sFinder = third.find(i);
if (sFinder != third.end())
sFinder->second = d[i];
else
third.insert(std::make_pair(i, d[i]));
}
#else
get<3>(a)[(u256)i] = d[i];
#endif
}
}
}
mObject exportExec()
{
mObject ret;
ret["address"] = toString(myAddress);
ret["sender"] = toString(txSender);
push(ret, "value", txValue);
mArray d;
for (auto const& i: txData)
push(d, i);
ret["data"] = d;
return ret;
}
void importExec(mObject& _o)
{
myAddress = Address(_o["address"].get_str());
txSender = Address(_o["sender"].get_str());
txValue = toInt(_o["value"]);
for (auto const& j: _o["data"].get_array())
txData.push_back(toInt(j));
}
mArray exportTxs()
{
mArray ret;
for (Transaction const& tx: txs)
{
mObject o;
o["destination"] = toString(tx.receiveAddress);
push(o, "value", tx.value);
mArray d;
for (auto const& i: tx.data)
push(d, i);
o["data"] = d;
ret.push_back(o);
}
return ret;
}
void importTxs(mArray& _txs)
{
for (mValue& v: _txs)
{
auto tx = v.get_obj();
Transaction t;
t.receiveAddress = Address(tx["destination"].get_str());
t.value = toInt(tx["value"]);
for (auto const& j: tx["data"].get_array())
t.data.push_back(toInt(j));
txs.push_back(t);
}
}
void reset(u256 _myBalance, u256 _myNonce, u256s _myData)
{
txs.clear();
addresses.clear();
set(myAddress, _myBalance, _myNonce, _myData);
}
map<Address, tuple<u256, u256, u256, map<u256, u256>>> addresses;
Transactions txs;
};
#define CREATE_TESTS 0
template <> class UnitTest<1>
{
public:
int operator()()
{
json_spirit::mValue v;
#if CREATE_TESTS
string s = asString(contents("../../cpp-ethereum/test/vmtests.json"));
json_spirit::read_string(s, v);
bool passed = doTests(v, true);
cout << json_spirit::write_string(v, true) << endl;
#else
string s = asString(contents("../../tests/vmtests.json"));
json_spirit::read_string(s, v);
bool passed = doTests(v, false);
#endif
return passed ? 0 : 1;
}
bool doTests(json_spirit::mValue& v, bool _fillin)
{
bool passed = true;
for (auto& i: v.get_obj())
{
cnote << i.first;
mObject& o = i.second.get_obj();
VM vm;
FakeExtVM fev;
fev.importEnv(o["env"].get_obj());
fev.importState(o["pre"].get_obj());
if (_fillin)
o["pre"] = mValue(fev.exportState());
for (auto i: o["exec"].get_array())
{
fev.importExec(i.get_obj());
vm.go(fev);
}
if (_fillin)
{
o["post"] = mValue(fev.exportState());
o["txs"] = fev.exportTxs();
}
else
{
FakeExtVM test;
test.importState(o["post"].get_obj());
test.importTxs(o["txs"].get_array());
if (test.addresses != fev.addresses)
{
cwarn << "Test failed: state different.";
passed = false;
}
if (test.txs != fev.txs)
{
cwarn << "Test failed: tx list different:";
cwarn << test.txs;
cwarn << fev.txs;
passed = false;
}
}
}
return passed;
}
string makeTestCase()
{
json_spirit::mObject o;
VM vm;
BlockInfo pb;
pb.hash = sha3("previousHash");
pb.nonce = sha3("previousNonce");
BlockInfo cb = pb;
cb.difficulty = 256;
cb.timestamp = 1;
cb.coinbaseAddress = toAddress(sha3("coinbase"));
FeeStructure fees;
fees.setMultiplier(1);
FakeExtVM fev(fees, pb, cb, 0);
fev.setContract(toAddress(sha3("contract")), ether, 0, compileLisp("(suicide (txsender))"));
o["env"] = fev.exportEnv();
o["pre"] = fev.exportState();
fev.setTransaction(toAddress(sha3("sender")), ether, u256s());
mArray execs;
execs.push_back(fev.exportExec());
o["exec"] = execs;
vm.go(fev);
o["post"] = fev.exportState();
o["txs"] = fev.exportTxs();
return json_spirit::write_string(json_spirit::mValue(o), true);
}
};
}
int vmTest()
{
return UnitTest<1>()();
}

84
test/vmtests.json

@ -0,0 +1,84 @@
{
"suicide": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"feeMultiplier" : 1
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : 1000000000000000000,
"nonce" : 0,
"code" : "(suicide (txsender))"
}
},
"exec" : [
{
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"sender" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : 1000000000000000000,
"data" : [
]
}
]
},
"mktx": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"feeMultiplier" : 1
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : 1000000000000000000,
"nonce" : 0,
"code" : "(mktx (txsender) 500000000000000000 0)"
}
},
"exec" : [
{
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"sender" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : 1000000000000000000,
"data" : [
]
}
]
},
"fan": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"feeMultiplier" : 1
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : 0,
"nonce" : 0,
"code" : "(seq (unless (gt (txvalue) 100finney) (stop)) (\"value\" (div (sub (txvalue) 100finney) (txdatan))) (\"i\" 0) (for (lt (\"i\") (txdatan)) (seq (mktx (txdata (\"i\")) (\"value\") 0) (\"i\" (add (\"i\") 1)) ) ) )"
}
},
"exec" : [
{
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"sender" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : 1000000000000000000,
"data" : [
"0xcd1722f3947def4cf144679da39c4c32bdc35681",
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
]
}
]
}
}

212
windows/Alethzero.vcxproj

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<RootNamespace>AlethZero</RootNamespace>
<ProjectName>AlethZero</ProjectName>
<ProjectGuid>{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
<Import Project="UseQt.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
<Import Project="UseQt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
<Import Project="CopyBinary.props" />
<Import Project="UseQt.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
<Import Project="CopyBinary.props" />
<Import Project="UseQt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LargeAddressAware>true</LargeAddressAware>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<LargeAddressAware>true</LargeAddressAware>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\windows\LibEthereum.vcxproj">
<Project>{826e68cb-d3ee-4a8a-b540-59a8c3f38d4f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\alethzero\main.cpp" />
<ClCompile Include="..\alethzero\MainWin.cpp" />
<ClCompile Include="qt_plugin_import.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="WinMain.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\alethzero\MainWin.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)moc_%(FileName).cpp</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)moc_%(FileName).cpp</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)moc_%(FileName).cpp</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)moc_%(FileName).cpp</Outputs>
</CustomBuild>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\alethzero\Main.ui">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)ui_%(FileName).h</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)ui_%(FileName).h</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)ui_%(FileName).h</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)"</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)ui_%(FileName).h</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

28
windows/Alethzero.vcxproj.filters

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\alethzero\main.cpp" />
<ClCompile Include="..\alethzero\MainWin.cpp" />
<ClCompile Include="stdafx.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="WinMain.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="qt_plugin_import.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Windows</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Windows">
<UniqueIdentifier>{049fb46c-1677-45cb-95ae-3a2d9e3090be}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\alethzero\MainWin.h" />
<CustomBuild Include="..\alethzero\Main.ui" />
</ItemGroup>
</Project>

18
windows/CopyBinary.props

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<PostBuildEvent>
<Command>xcopy /F /Y $(OutDir)$(TargetName)$(TargetExt) ..\..\_binaries\$(Platform)\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<PostBuildEvent>
<Message>
</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

121
windows/Ethereum.sln

@ -0,0 +1,121 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{988F2383-FA1D-408B-BCF6-C0EE7AB0A560}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{6838FA95-01BF-4FF7-914C-FC209B81406E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibEthereum", "LibEthereum.vcxproj", "{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibLevelDB", "LibLevelDB.vcxproj", "{27014763-955D-486B-9BA7-69872192E6F4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibSecp256k1", "LibSecp256k1.vcxproj", "{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ethereum", "Ethereum.vcxproj", "{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSecp256k1", "TestSecp256k1.vcxproj", "{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestEthereum", "TestEthereum.vcxproj", "{3F3E389B-88DE-41D5-A73B-4F6036E18B36}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibCryptoPP", "LibCryptoPP.vcxproj", "{1CC213A4-3482-4211-B47B-172E90DAC7DE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibMiniUPnPc", "LibMiniUPnPc.vcxproj", "{1B1CA20E-39C3-4D9B-AC37-3783048E6672}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Alethzero", "Alethzero.vcxproj", "{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|Win32.ActiveCfg = Debug|Win32
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|Win32.Build.0 = Debug|Win32
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|x64.ActiveCfg = Debug|x64
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|x64.Build.0 = Debug|x64
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|Win32.ActiveCfg = Release|Win32
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|Win32.Build.0 = Release|Win32
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|x64.ActiveCfg = Release|x64
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|x64.Build.0 = Release|x64
{27014763-955D-486B-9BA7-69872192E6F4}.Debug|Win32.ActiveCfg = Debug|Win32
{27014763-955D-486B-9BA7-69872192E6F4}.Debug|Win32.Build.0 = Debug|Win32
{27014763-955D-486B-9BA7-69872192E6F4}.Debug|x64.ActiveCfg = Debug|x64
{27014763-955D-486B-9BA7-69872192E6F4}.Debug|x64.Build.0 = Debug|x64
{27014763-955D-486B-9BA7-69872192E6F4}.Release|Win32.ActiveCfg = Release|Win32
{27014763-955D-486B-9BA7-69872192E6F4}.Release|Win32.Build.0 = Release|Win32
{27014763-955D-486B-9BA7-69872192E6F4}.Release|x64.ActiveCfg = Release|x64
{27014763-955D-486B-9BA7-69872192E6F4}.Release|x64.Build.0 = Release|x64
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|Win32.ActiveCfg = Debug|Win32
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|Win32.Build.0 = Debug|Win32
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|x64.ActiveCfg = Debug|x64
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|x64.Build.0 = Debug|x64
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|Win32.ActiveCfg = Release|Win32
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|Win32.Build.0 = Release|Win32
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|x64.ActiveCfg = Release|x64
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|x64.Build.0 = Release|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|Win32.ActiveCfg = Debug|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|Win32.Build.0 = Debug|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|x64.ActiveCfg = Debug|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|x64.Build.0 = Debug|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|Win32.ActiveCfg = Release|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|Win32.Build.0 = Release|Win32
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|x64.ActiveCfg = Release|x64
{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|x64.Build.0 = Release|x64
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|Win32.ActiveCfg = Debug|Win32
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|Win32.Build.0 = Debug|Win32
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|x64.ActiveCfg = Debug|x64
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|x64.Build.0 = Debug|x64
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|Win32.ActiveCfg = Release|Win32
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|Win32.Build.0 = Release|Win32
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|x64.ActiveCfg = Release|x64
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|x64.Build.0 = Release|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|Win32.ActiveCfg = Debug|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|Win32.Build.0 = Debug|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|x64.ActiveCfg = Debug|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|x64.Build.0 = Debug|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|Win32.ActiveCfg = Release|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|Win32.Build.0 = Release|Win32
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|x64.ActiveCfg = Release|x64
{3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|x64.Build.0 = Release|x64
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|Win32.ActiveCfg = Debug|Win32
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|Win32.Build.0 = Debug|Win32
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|x64.ActiveCfg = Debug|x64
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|x64.Build.0 = Debug|x64
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|Win32.ActiveCfg = Release|Win32
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|Win32.Build.0 = Release|Win32
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|x64.ActiveCfg = Release|x64
{1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|x64.Build.0 = Release|x64
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|Win32.ActiveCfg = Debug|Win32
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|Win32.Build.0 = Debug|Win32
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|x64.ActiveCfg = Debug|x64
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|x64.Build.0 = Debug|x64
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|Win32.ActiveCfg = Release|Win32
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|Win32.Build.0 = Release|Win32
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|x64.ActiveCfg = Release|x64
{1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|x64.Build.0 = Release|x64
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|Win32.ActiveCfg = Debug|Win32
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|Win32.Build.0 = Debug|Win32
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|x64.ActiveCfg = Debug|x64
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|x64.Build.0 = Debug|x64
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|Win32.ActiveCfg = Release|Win32
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|Win32.Build.0 = Release|Win32
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|x64.ActiveCfg = Release|x64
{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560}
{27014763-955D-486B-9BA7-69872192E6F4} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560}
{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560}
{1CC213A4-3482-4211-B47B-172E90DAC7DE} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560}
{1B1CA20E-39C3-4D9B-AC37-3783048E6672} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560}
{3BF049F8-AF7E-4E1C-9627-3E94C887AF24} = {6838FA95-01BF-4FF7-914C-FC209B81406E}
{3F3E389B-88DE-41D5-A73B-4F6036E18B36} = {6838FA95-01BF-4FF7-914C-FC209B81406E}
EndGlobalSection
EndGlobal

48
eth/Ethereum.vcxproj → windows/Ethereum.vcxproj

@ -29,59 +29,60 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
<Import Project="CopyBinary.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
<Import Project="CopyBinary.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>eth</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetName>eth</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>eth</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>eth</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -89,12 +90,8 @@
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -108,12 +105,8 @@
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -128,13 +121,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -152,13 +141,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -168,15 +153,12 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\..\cryptopp562\cryptlib.vcxproj">
<Project>{3423ec9a-52e4-4a4d-9753-edebc38785ef}</Project>
</ProjectReference>
<ProjectReference Include="..\libethereum\LibEthereum.vcxproj">
<Project>{7050c7cf-7551-48be-8e57-92235906c13a}</Project>
<ProjectReference Include="..\windows\LibEthereum.vcxproj">
<Project>{826e68cb-d3ee-4a8a-b540-59a8c3f38d4f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="..\eth\main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

176
windows/LibCryptoPP.vcxproj

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\cryptopp\algparam.cpp" />
<ClCompile Include="..\..\cryptopp\cpu.cpp" />
<ClCompile Include="..\..\cryptopp\cryptlib.cpp" />
<ClCompile Include="..\..\cryptopp\filters.cpp" />
<ClCompile Include="..\..\cryptopp\fips140.cpp" />
<ClCompile Include="..\..\cryptopp\iterhash.cpp" />
<ClCompile Include="..\..\cryptopp\misc.cpp" />
<ClCompile Include="..\..\cryptopp\mqueue.cpp" />
<ClCompile Include="..\..\cryptopp\queue.cpp" />
<ClCompile Include="..\..\cryptopp\rdtables.cpp" />
<ClCompile Include="..\..\cryptopp\rijndael.cpp" />
<ClCompile Include="..\..\cryptopp\ripemd.cpp" />
<ClCompile Include="..\..\cryptopp\sha.cpp" />
<ClCompile Include="..\..\cryptopp\sha3.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\cryptopp\algparam.h" />
<ClInclude Include="..\..\cryptopp\cpu.h" />
<ClInclude Include="..\..\cryptopp\cryptlib.h" />
<ClInclude Include="..\..\cryptopp\filters.h" />
<ClInclude Include="..\..\cryptopp\fips140.h" />
<ClInclude Include="..\..\cryptopp\iterhash.h" />
<ClInclude Include="..\..\cryptopp\misc.h" />
<ClInclude Include="..\..\cryptopp\mqueue.h" />
<ClInclude Include="..\..\cryptopp\queue.h" />
<ClInclude Include="..\..\cryptopp\rijndael.h" />
<ClInclude Include="..\..\cryptopp\ripemd.h" />
<ClInclude Include="..\..\cryptopp\sha.h" />
<ClInclude Include="..\..\cryptopp\sha3.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\cryptopp\x64dll.asm">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ml64.exe /c /nologo /Fo"$(IntDir)x64dll.obj" /Zi "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ml64.exe /c /nologo /Fo"$(IntDir)x64dll.obj" /Zi "%(FullPath)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)x64dll.obj</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)x64dll.obj</Outputs>
</CustomBuild>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<RootNamespace>LibCryptoPP</RootNamespace>
<ProjectGuid>{1CC213A4-3482-4211-B47B-172E90DAC7DE}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

31
windows/LibEthereum.props

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<BoostDir>../../boost</BoostDir>
</PropertyGroup>
<PropertyGroup>
<OutDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<IntDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<DisableSpecificWarnings>4068;4100;4127;4258;4505;4512;4706</DisableSpecificWarnings>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>include/$(ProjectName);../libethereum;$(BoostDir);../../leveldb/include;../../cryptopp;../secp256k1;../../miniupnp</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ETH_BUILD_PLATFORM=Windows/VS2013;ETH_BUILD_TYPE=$(Configuration)-$(Platform);STATICLIB;LEVELDB_PLATFORM_WINDOWS;USE_NUM_BOOST;USE_FIELD_10X26;USE_FIELD_INV_BUILTIN;_WIN32_WINNT=0x0501;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(BoostDir)/stage/$(Platform)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<BuildMacro Include="BoostDir">
<Value>$(BoostDir)</Value>
</BuildMacro>
</ItemGroup>
</Project>

218
windows/LibEthereum.vcxproj

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\libethereum\AddressState.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\libethereum\BlockChain.cpp" />
<ClCompile Include="..\libethereum\BlockInfo.cpp" />
<ClCompile Include="..\libethereum\Client.cpp" />
<ClCompile Include="..\libethereum\Common.cpp" />
<ClCompile Include="..\libethereum\Dagger.cpp" />
<ClCompile Include="..\libethereum\Defaults.cpp" />
<ClCompile Include="..\libethereum\FeeStructure.cpp" />
<ClCompile Include="..\libethereum\FileSystem.cpp" />
<ClCompile Include="..\libethereum\Instruction.cpp" />
<ClCompile Include="..\libethereum\MemTrie.cpp" />
<ClCompile Include="..\libethereum\PeerNetwork.cpp" />
<ClCompile Include="..\libethereum\RLP.cpp" />
<ClCompile Include="..\libethereum\State.cpp" />
<ClCompile Include="..\libethereum\Transaction.cpp" />
<ClCompile Include="..\libethereum\TransactionQueue.cpp" />
<ClCompile Include="..\libethereum\TrieCommon.cpp" />
<ClCompile Include="..\libethereum\TrieDB.cpp" />
<ClCompile Include="..\libethereum\TrieHash.cpp" />
<ClCompile Include="..\libethereum\UPnP.cpp" />
<ClCompile Include="..\libethereum\VM.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdafx.h</PrecompiledHeaderFile>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\libethereum\AddressState.h" />
<ClInclude Include="..\libethereum\BlockChain.h" />
<ClInclude Include="..\libethereum\BlockInfo.h" />
<ClInclude Include="..\libethereum\Client.h" />
<ClInclude Include="..\libethereum\Common.h" />
<ClInclude Include="..\libethereum\Dagger.h" />
<ClInclude Include="..\libethereum\Defaults.h" />
<ClInclude Include="..\libethereum\Exceptions.h" />
<ClInclude Include="..\libethereum\ExtVMFace.h" />
<ClInclude Include="..\libethereum\FeeStructure.h" />
<ClInclude Include="..\libethereum\FileSystem.h" />
<ClInclude Include="..\libethereum\Instruction.h" />
<ClInclude Include="..\libethereum\MemTrie.h" />
<ClInclude Include="..\libethereum\PeerNetwork.h" />
<ClInclude Include="..\libethereum\RLP.h" />
<ClInclude Include="..\libethereum\State.h" />
<ClInclude Include="..\libethereum\Transaction.h" />
<ClInclude Include="..\libethereum\TransactionQueue.h" />
<ClInclude Include="..\libethereum\TrieCommon.h" />
<ClInclude Include="..\libethereum\TrieDB.h" />
<ClInclude Include="..\libethereum\TrieHash.h" />
<ClInclude Include="..\libethereum\UPnP.h" />
<ClInclude Include="..\libethereum\vector_ref.h" />
<ClInclude Include="..\libethereum\VM.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="LibCryptoPP.vcxproj">
<Project>{1cc213a4-3482-4211-b47b-172e90dac7de}</Project>
</ProjectReference>
<ProjectReference Include="LibLevelDB.vcxproj">
<Project>{27014763-955d-486b-9ba7-69872192e6f4}</Project>
</ProjectReference>
<ProjectReference Include="LibMiniUPnPc.vcxproj">
<Project>{1b1ca20e-39c3-4d9b-ac37-3783048e6672}</Project>
</ProjectReference>
<ProjectReference Include="LibSecp256k1.vcxproj">
<Project>{1e1175bb-c4a9-41d8-b2d1-9022f71d3cea}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LibEthereum</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib />
<ProjectReference />
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

63
windows/LibEthereum.vcxproj.filters

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\libethereum\BlockInfo.cpp" />
<ClCompile Include="..\libethereum\Client.cpp" />
<ClCompile Include="..\libethereum\Common.cpp" />
<ClCompile Include="..\libethereum\Dagger.cpp" />
<ClCompile Include="..\libethereum\Defaults.cpp" />
<ClCompile Include="..\libethereum\FileSystem.cpp" />
<ClCompile Include="..\libethereum\MemTrie.cpp" />
<ClCompile Include="..\libethereum\PeerNetwork.cpp" />
<ClCompile Include="..\libethereum\RLP.cpp" />
<ClCompile Include="..\libethereum\State.cpp" />
<ClCompile Include="..\libethereum\Transaction.cpp" />
<ClCompile Include="..\libethereum\TransactionQueue.cpp" />
<ClCompile Include="..\libethereum\TrieCommon.cpp" />
<ClCompile Include="..\libethereum\TrieDB.cpp" />
<ClCompile Include="..\libethereum\TrieHash.cpp" />
<ClCompile Include="..\libethereum\UPnP.cpp" />
<ClCompile Include="..\libethereum\AddressState.cpp" />
<ClCompile Include="..\libethereum\BlockChain.cpp" />
<ClCompile Include="..\libethereum\Instruction.cpp" />
<ClCompile Include="stdafx.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\libethereum\FeeStructure.cpp" />
<ClCompile Include="..\libethereum\VM.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\libethereum\BlockInfo.h" />
<ClInclude Include="..\libethereum\Client.h" />
<ClInclude Include="..\libethereum\Common.h" />
<ClInclude Include="..\libethereum\Dagger.h" />
<ClInclude Include="..\libethereum\Defaults.h" />
<ClInclude Include="..\libethereum\Exceptions.h" />
<ClInclude Include="..\libethereum\FileSystem.h" />
<ClInclude Include="..\libethereum\Instruction.h" />
<ClInclude Include="..\libethereum\MemTrie.h" />
<ClInclude Include="..\libethereum\PeerNetwork.h" />
<ClInclude Include="..\libethereum\RLP.h" />
<ClInclude Include="..\libethereum\State.h" />
<ClInclude Include="..\libethereum\Transaction.h" />
<ClInclude Include="..\libethereum\TransactionQueue.h" />
<ClInclude Include="..\libethereum\TrieCommon.h" />
<ClInclude Include="..\libethereum\TrieDB.h" />
<ClInclude Include="..\libethereum\TrieHash.h" />
<ClInclude Include="..\libethereum\UPnP.h" />
<ClInclude Include="..\libethereum\vector_ref.h" />
<ClInclude Include="..\libethereum\AddressState.h" />
<ClInclude Include="..\libethereum\BlockChain.h" />
<ClInclude Include="stdafx.h">
<Filter>Windows</Filter>
</ClInclude>
<ClInclude Include="..\libethereum\ExtVMFace.h" />
<ClInclude Include="..\libethereum\FeeStructure.h" />
<ClInclude Include="..\libethereum\VM.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="Windows">
<UniqueIdentifier>{2d571d8f-bacf-4c49-a0d0-c9036f5c0cc9}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

223
windows/LibLevelDB.vcxproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\leveldb\db\builder.h" />
<ClInclude Include="..\..\leveldb\db\dbformat.h" />
<ClInclude Include="..\..\leveldb\db\db_impl.h" />
<ClInclude Include="..\..\leveldb\db\db_iter.h" />
<ClInclude Include="..\..\leveldb\db\filename.h" />
<ClInclude Include="..\..\leveldb\db\log_format.h" />
<ClInclude Include="..\..\leveldb\db\log_reader.h" />
<ClInclude Include="..\..\leveldb\db\log_writer.h" />
<ClInclude Include="..\..\leveldb\db\memtable.h" />
<ClInclude Include="..\..\leveldb\db\skiplist.h" />
<ClInclude Include="..\..\leveldb\db\snapshot.h" />
<ClInclude Include="..\..\leveldb\db\table_cache.h" />
<ClInclude Include="..\..\leveldb\db\version_edit.h" />
<ClInclude Include="..\..\leveldb\db\version_set.h" />
<ClInclude Include="..\..\leveldb\db\write_batch_internal.h" />
<ClInclude Include="..\..\leveldb\port\atomic_pointer.h" />
<ClInclude Include="..\..\leveldb\port\port.h" />
<ClInclude Include="..\..\leveldb\port\port_win.h" />
<ClInclude Include="..\..\leveldb\table\block.h" />
<ClInclude Include="..\..\leveldb\table\block_builder.h" />
<ClInclude Include="..\..\leveldb\table\format.h" />
<ClInclude Include="..\..\leveldb\table\iterator_wrapper.h" />
<ClInclude Include="..\..\leveldb\table\merger.h" />
<ClInclude Include="..\..\leveldb\table\two_level_iterator.h" />
<ClInclude Include="..\..\leveldb\util\arena.h" />
<ClInclude Include="..\..\leveldb\util\coding.h" />
<ClInclude Include="..\..\leveldb\util\crc32c.h" />
<ClInclude Include="..\..\leveldb\util\hash.h" />
<ClInclude Include="..\..\leveldb\util\histogram.h" />
<ClInclude Include="..\..\leveldb\util\logging.h" />
<ClInclude Include="..\..\leveldb\util\mutexlock.h" />
<ClInclude Include="..\..\leveldb\util\posix_logger.h" />
<ClInclude Include="..\..\leveldb\util\random.h" />
<ClInclude Include="..\..\leveldb\util\testharness.h" />
<ClInclude Include="..\..\leveldb\util\testutil.h" />
<ClInclude Include="..\..\leveldb\util\win_logger.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\leveldb\db\builder.cc" />
<ClCompile Include="..\..\leveldb\db\c.cc" />
<ClCompile Include="..\..\leveldb\db\dbformat.cc" />
<ClCompile Include="..\..\leveldb\db\db_bench.cc" />
<ClCompile Include="..\..\leveldb\db\db_impl.cc" />
<ClCompile Include="..\..\leveldb\db\db_iter.cc" />
<ClCompile Include="..\..\leveldb\db\filename.cc" />
<ClCompile Include="..\..\leveldb\db\log_reader.cc" />
<ClCompile Include="..\..\leveldb\db\log_writer.cc" />
<ClCompile Include="..\..\leveldb\db\memtable.cc" />
<ClCompile Include="..\..\leveldb\db\repair.cc" />
<ClCompile Include="..\..\leveldb\db\table_cache.cc" />
<ClCompile Include="..\..\leveldb\db\version_edit.cc" />
<ClCompile Include="..\..\leveldb\db\version_set.cc" />
<ClCompile Include="..\..\leveldb\db\write_batch.cc" />
<ClCompile Include="..\..\leveldb\port\port_win.cc" />
<ClCompile Include="..\..\leveldb\table\block.cc" />
<ClCompile Include="..\..\leveldb\table\block_builder.cc" />
<ClCompile Include="..\..\leveldb\table\format.cc" />
<ClCompile Include="..\..\leveldb\table\iterator.cc" />
<ClCompile Include="..\..\leveldb\table\merger.cc" />
<ClCompile Include="..\..\leveldb\table\table.cc" />
<ClCompile Include="..\..\leveldb\table\table_builder.cc" />
<ClCompile Include="..\..\leveldb\table\two_level_iterator.cc" />
<ClCompile Include="..\..\leveldb\util\arena.cc" />
<ClCompile Include="..\..\leveldb\util\cache.cc" />
<ClCompile Include="..\..\leveldb\util\coding.cc" />
<ClCompile Include="..\..\leveldb\util\comparator.cc" />
<ClCompile Include="..\..\leveldb\util\crc32c.cc" />
<ClCompile Include="..\..\leveldb\util\env.cc" />
<ClCompile Include="..\..\leveldb\util\env_boost.cc" />
<ClCompile Include="..\..\leveldb\util\hash.cc" />
<ClCompile Include="..\..\leveldb\util\histogram.cc" />
<ClCompile Include="..\..\leveldb\util\logging.cc" />
<ClCompile Include="..\..\leveldb\util\options.cc" />
<ClCompile Include="..\..\leveldb\util\status.cc" />
<ClCompile Include="..\..\leveldb\util\testharness.cc" />
<ClCompile Include="..\..\leveldb\util\testutil.cc" />
<ClCompile Include="..\..\leveldb\util\win_logger.cc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{27014763-955D-486B-9BA7-69872192E6F4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LibLevelDB</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);../../leveldb</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4018;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);../../leveldb</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4018;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);../../leveldb</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4018;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);../../leveldb</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4018;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

246
windows/LibLevelDB.vcxproj.filters

@ -0,0 +1,246 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="db">
<UniqueIdentifier>{d83904b1-b5d1-4c5b-b476-96f08300d103}</UniqueIdentifier>
</Filter>
<Filter Include="util">
<UniqueIdentifier>{72573022-b7fd-4b7a-a92e-a68c06bd6366}</UniqueIdentifier>
</Filter>
<Filter Include="table">
<UniqueIdentifier>{7f821e9e-4ebf-4d18-8fb4-898bd3d81376}</UniqueIdentifier>
</Filter>
<Filter Include="port">
<UniqueIdentifier>{f285a595-6c39-4350-8d30-6f696a3a7c4c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\leveldb\db\table_cache.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\version_edit.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\version_set.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\write_batch_internal.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\builder.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\db_impl.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\db_iter.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\dbformat.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\filename.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\log_format.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\log_reader.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\log_writer.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\memtable.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\skiplist.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\db\snapshot.h">
<Filter>db</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\table\merger.h">
<Filter>table</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\table\two_level_iterator.h">
<Filter>table</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\table\block.h">
<Filter>table</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\table\block_builder.h">
<Filter>table</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\table\format.h">
<Filter>table</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\table\iterator_wrapper.h">
<Filter>table</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\posix_logger.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\random.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\testharness.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\testutil.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\win_logger.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\arena.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\coding.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\crc32c.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\hash.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\histogram.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\logging.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\util\mutexlock.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\port\port_win.h">
<Filter>port</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\port\atomic_pointer.h">
<Filter>port</Filter>
</ClInclude>
<ClInclude Include="..\..\leveldb\port\port.h">
<Filter>port</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\leveldb\db\version_edit.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\version_set.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\write_batch.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\builder.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\c.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\db_bench.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\db_impl.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\db_iter.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\dbformat.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\filename.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\log_reader.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\log_writer.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\memtable.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\repair.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\db\table_cache.cc">
<Filter>db</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\merger.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\table.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\table_builder.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\two_level_iterator.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\block.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\block_builder.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\format.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\table\iterator.cc">
<Filter>table</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\status.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\testharness.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\testutil.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\win_logger.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\arena.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\cache.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\coding.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\comparator.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\crc32c.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\env.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\env_boost.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\hash.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\histogram.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\logging.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\util\options.cc">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="..\..\leveldb\port\port_win.cc">
<Filter>port</Filter>
</ClCompile>
</ItemGroup>
</Project>

184
windows/LibMiniUPnPc.vcxproj

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\miniupnp\miniupnpc\bsdqueue.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\codelength.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\connecthostport.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\declspec.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\igd_desc_parse.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\minisoap.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\minissdpc.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\miniupnpc.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\miniupnpctypes.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\miniwget.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\minixml.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\portlistingparse.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\receivedata.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\upnpcommands.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\upnperrors.h" />
<ClInclude Include="..\..\miniupnp\miniupnpc\upnpreplyparse.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\miniupnp\miniupnpc\connecthostport.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\igd_desc_parse.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\minisoap.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\miniupnpc.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\miniwget.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\minixml.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\portlistingparse.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\receivedata.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\upnpcommands.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\upnperrors.c" />
<ClCompile Include="..\..\miniupnp\miniupnpc\upnpreplyparse.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<RootNamespace>LibMiniUPnPc</RootNamespace>
<ProjectGuid>{1B1CA20E-39C3-4D9B-AC37-3783048E6672}</ProjectGuid>
<ProjectName>LibMiniUPnPc</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4244;4245;4267;4389;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>Iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4244;4245;4267;4389;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>Iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4244;4245;4267;4389;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalDependencies>Iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<DisableSpecificWarnings>4244;4245;4267;4389;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalDependencies>Iphlpapi.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

110
libethereum/LibEthereum.vcxproj → windows/LibSecp256k1.vcxproj

@ -19,65 +19,73 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AddressState.h" />
<ClInclude Include="BlockChain.h" />
<ClInclude Include="BlockInfo.h" />
<ClInclude Include="Common.h" />
<ClInclude Include="Dagger.h" />
<ClInclude Include="Exceptions.h" />
<ClInclude Include="Instruction.h" />
<ClInclude Include="PeerNetwork.h" />
<ClInclude Include="RLP.h" />
<ClInclude Include="State.h" />
<ClInclude Include="Transaction.h" />
<ClInclude Include="TransactionQueue.h" />
<ClInclude Include="Trie.h" />
<ClInclude Include="vector_ref.h" />
<ClInclude Include="..\secp256k1\ecdsa.h" />
<ClInclude Include="..\secp256k1\ecmult.h" />
<ClInclude Include="..\secp256k1\field.h" />
<ClInclude Include="..\secp256k1\field_10x26.h" />
<ClInclude Include="..\secp256k1\field_5x52.h" />
<ClInclude Include="..\secp256k1\field_gmp.h" />
<ClInclude Include="..\secp256k1\group.h" />
<ClInclude Include="..\secp256k1\impl\ecdsa.h" />
<ClInclude Include="..\secp256k1\impl\ecmult.h" />
<ClInclude Include="..\secp256k1\impl\field.h" />
<ClInclude Include="..\secp256k1\impl\field_10x26.h" />
<ClInclude Include="..\secp256k1\impl\field_5x52.h" />
<ClInclude Include="..\secp256k1\impl\field_5x52_asm.h" />
<ClInclude Include="..\secp256k1\impl\field_5x52_int128.h" />
<ClInclude Include="..\secp256k1\impl\field_gmp.h" />
<ClInclude Include="..\secp256k1\impl\group.h" />
<ClInclude Include="..\secp256k1\impl\num.h" />
<ClInclude Include="..\secp256k1\impl\num_boost.h" />
<ClInclude Include="..\secp256k1\impl\num_gmp.h" />
<ClInclude Include="..\secp256k1\impl\num_openssl.h" />
<ClInclude Include="..\secp256k1\impl\util.h" />
<ClInclude Include="..\secp256k1\num.h" />
<ClInclude Include="..\secp256k1\num_boost.h" />
<ClInclude Include="..\secp256k1\num_gmp.h" />
<ClInclude Include="..\secp256k1\num_openssl.h" />
<ClInclude Include="..\secp256k1\secp256k1.h" />
<ClInclude Include="..\secp256k1\util.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AddressState.cpp" />
<ClCompile Include="BlockChain.cpp" />
<ClCompile Include="BlockInfo.cpp" />
<ClCompile Include="Common.cpp" />
<ClCompile Include="Dagger.cpp" />
<ClCompile Include="PeerNetwork.cpp" />
<ClCompile Include="RLP.cpp" />
<ClCompile Include="State.cpp" />
<ClCompile Include="Transaction.cpp" />
<ClCompile Include="TransactionQueue.cpp" />
<ClCompile Include="Trie.cpp" />
<ClCompile Include="..\secp256k1\secp256k1.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\secp256k1\field_5x52_asm.asm" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7050C7CF-7551-48BE-8E57-92235906C13A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LibEthereum</RootNamespace>
<RootNamespace>LibSecp256k1</RootNamespace>
<ProjectGuid>{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}</ProjectGuid>
<ProjectName>LibSecp256k1</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -99,25 +107,19 @@
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<IntDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<IntDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<IntDir>..\build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -126,11 +128,13 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -139,12 +143,15 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -155,12 +162,15 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

71
windows/LibSecp256k1.vcxproj.filters

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="impl">
<UniqueIdentifier>{7d4db365-bce7-45c1-861c-f5f86beca992}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\secp256k1\impl\group.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\num.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\num_boost.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\num_gmp.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\num_openssl.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\util.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\ecdsa.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\ecmult.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\field.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\field_5x52.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\field_5x52_asm.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\field_5x52_int128.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\field_10x26.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\impl\field_gmp.h">
<Filter>impl</Filter>
</ClInclude>
<ClInclude Include="..\secp256k1\group.h" />
<ClInclude Include="..\secp256k1\num.h" />
<ClInclude Include="..\secp256k1\num_boost.h" />
<ClInclude Include="..\secp256k1\num_gmp.h" />
<ClInclude Include="..\secp256k1\num_openssl.h" />
<ClInclude Include="..\secp256k1\secp256k1.h" />
<ClInclude Include="..\secp256k1\util.h" />
<ClInclude Include="..\secp256k1\ecdsa.h" />
<ClInclude Include="..\secp256k1\ecmult.h" />
<ClInclude Include="..\secp256k1\field.h" />
<ClInclude Include="..\secp256k1\field_5x52.h" />
<ClInclude Include="..\secp256k1\field_10x26.h" />
<ClInclude Include="..\secp256k1\field_gmp.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\secp256k1\secp256k1.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\secp256k1\field_5x52_asm.asm" />
</ItemGroup>
</Project>

181
windows/TestEthereum.vcxproj

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<RootNamespace>TestEthereum</RootNamespace>
<ProjectName>TestEthereum</ProjectName>
<ProjectGuid>{3F3E389B-88DE-41D5-A73B-4F6036E18B36}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<OpenMPSupport>true</OpenMPSupport>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LargeAddressAware>true</LargeAddressAware>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OpenMPSupport>true</OpenMPSupport>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<LargeAddressAware>true</LargeAddressAware>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OpenMPSupport>true</OpenMPSupport>
<ForcedIncludeFiles>stdafx.h</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="LibEthereum.vcxproj">
<Project>{826e68cb-d3ee-4a8a-b540-59a8c3f38d4f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test\crypto.cpp" />
<ClCompile Include="..\test\dagger.cpp" />
<ClCompile Include="..\test\hexPrefix.cpp" />
<ClCompile Include="..\test\main.cpp" />
<ClCompile Include="..\test\peer.cpp" />
<ClCompile Include="..\test\rlp.cpp" />
<ClCompile Include="..\test\state.cpp" />
<ClCompile Include="..\test\trie.cpp" />
<ClCompile Include="..\test\vm.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

27
windows/TestEthereum.vcxproj.filters

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\test\crypto.cpp" />
<ClCompile Include="..\test\dagger.cpp" />
<ClCompile Include="..\test\hexPrefix.cpp" />
<ClCompile Include="..\test\main.cpp" />
<ClCompile Include="..\test\peer.cpp" />
<ClCompile Include="..\test\rlp.cpp" />
<ClCompile Include="..\test\state.cpp" />
<ClCompile Include="..\test\trie.cpp" />
<ClCompile Include="..\test\vm.cpp" />
<ClCompile Include="stdafx.cpp">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Windows">
<UniqueIdentifier>{0acd7e2f-2594-4c13-94cb-3247045bdbfd}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Windows</Filter>
</ClInclude>
</ItemGroup>
</Project>

63
test/Test.vcxproj → windows/TestSecp256k1.vcxproj

@ -18,57 +18,66 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\secp256k1\tests.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="LibSecp256k1.vcxproj">
<Project>{1e1175bb-c4a9-41d8-b2d1-9022f71d3cea}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
<RootNamespace>Test</RootNamespace>
<ProjectName>Test</ProjectName>
<ProjectGuid>{3F3E389B-88DE-41D5-A73B-4F6036E18B36}</ProjectGuid>
<RootNamespace>TestSecp256k1</RootNamespace>
<ProjectName>TestSecp256k1</ProjectName>
<ProjectGuid>{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\libethereum\LibEthereum.props" />
<Import Project="LibEthereum.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -89,12 +98,10 @@
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -108,12 +115,9 @@
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -128,13 +132,11 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -152,13 +154,11 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../libethereum</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StringPooling>true</StringPooling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>true</OpenMPSupport>
<DisableSpecificWarnings>4351</DisableSpecificWarnings>
<DisableSpecificWarnings>4189;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -167,17 +167,6 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\..\cryptopp562\cryptlib.vcxproj">
<Project>{3423ec9a-52e4-4a4d-9753-edebc38785ef}</Project>
</ProjectReference>
<ProjectReference Include="..\libethereum\LibEthereum.vcxproj">
<Project>{7050c7cf-7551-48be-8e57-92235906c13a}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

38
windows/UseQt.props

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<QtDir>../../Qt/$(Platform)</QtDir>
<QtBin>$(QtDir)/qtbase/bin</QtBin>
<QtInclude>$(QtDir)/qtbase/include;../../Qt/Src/qtbase/include</QtInclude>
<QtLib>$(QtDir)/qtbase/lib;$(QtDir)/qtbase/plugins/platforms</QtLib>
<Lua>../../lua/lua</Lua>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup>
<Link />
<ClCompile>
<AdditionalIncludeDirectories>..;$(IntDir);$(QtInclude);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(QtLib);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<BuildMacro Include="QtDir">
<Value>$(QtDir)</Value>
</BuildMacro>
<BuildMacro Include="QtBin">
<Value>$(QtBin)</Value>
</BuildMacro>
<BuildMacro Include="QtInclude">
<Value>$(QtInclude)</Value>
</BuildMacro>
<BuildMacro Include="QtLib">
<Value>$(QtLib)</Value>
</BuildMacro>
<BuildMacro Include="Lua">
<Value>$(Lua)</Value>
</BuildMacro>
</ItemGroup>
</Project>

72
windows/WinMain.cpp

@ -0,0 +1,72 @@
// http://www.flipcode.com/archives/WinMain_Command_Line_Parser.shtml
// COTD Entry submitted by Max McGuire [amcguire@andrew.cmu.edu]
#include <windows.h>
extern int main(int argc, char* argv[]);
int WINAPI WinMain(HINSTANCE instance, HINSTANCE prev_instance, char* command_line, int show_command)
{
int argc;
char** argv;
char* arg;
int index;
int result;
// count the arguments
argc = 1;
arg = command_line;
while (arg[0] != 0)
{
while (arg[0] != 0 && arg[0] == ' ')
{
arg++;
}
if (arg[0] != 0)
{
argc++;
while (arg[0] != 0 && arg[0] != ' ')
{
arg++;
}
}
}
// tokenize the arguments
argv = (char**)malloc(argc * sizeof(char*));
arg = command_line;
index = 1;
while (arg[0] != 0)
{
while (arg[0] != 0 && arg[0] == ' ')
{
arg++;
}
if (arg[0] != 0)
{
argv[index] = arg;
index++;
while (arg[0] != 0 && arg[0] != ' ')
{
arg++;
}
if (arg[0] != 0)
{
arg[0] = 0;
arg++;
}
}
}
// put the program name into argv[0]
char filename[_MAX_PATH];
GetModuleFileName(NULL, filename, _MAX_PATH);
argv[0] = filename;
// call the user specified main function
result = main(argc, argv);
free(argv);
return result;
}

160
windows/bootstrap.sh

@ -0,0 +1,160 @@
#!/bin/bash
# @file bootstrap.sh
# @author Tim Hughes <tim@twistedfury.com>
# @date 2014
# Script to fetch and compile depdencies for building Ethereum using Visual Studio Express 2013.
# Prerequisites:
# - Visual Studio Express 2013 for Desktop
# - On PATH: bash, git, git-svn, curl, sed, 7z
error_exit() {
echo $1 1>&2
exit 1
}
for i in python perl curl git sed 7z; do
which $i &>/dev/null || error_exit "Could not find $i on PATH"
done
if [ ! -d "$VS120COMNTOOLS" ]; then
error_exit "Couldn't find Visual Studio 2013"
fi
if [[ ! $@ ]] || [ $1 == "fetch" ]; then
# fetch ethereum (develop branch)
if [ ! -d cpp-ethereum ]; then
(set -x; git clone https://github.com/ethereum/cpp-ethereum.git)
cd cpp-ethereum
(set -x; git checkout -b develop origin/develop)
cd ..
echo
fi
# fetch CryptoPP-5.6.2
if [ ! -d cryptopp ]; then
(set -x; git svn clone -r 541:541 http://svn.code.sf.net/p/cryptopp/code/trunk/c5 cryptopp)
echo
fi
# fetch MiniUPnP-1.8
if [ ! -d miniupnp ]; then
(set -x; git clone https://github.com/miniupnp/miniupnp.git)
cd miniupnp
(set -x; git checkout tags/miniupnpd_1_8)
cd ..
echo
fi
# fetch LevelDB (windows branch)
if [ ! -d leveldb ]; then
(set -x; git clone https://code.google.com/p/leveldb/)
cd leveldb
(set -x; git checkout origin/windows)
cd ..
echo
fi
# fetch and unpack boost-1.55 source
if [ ! -d boost ]; then
if [ ! -f _download/boost_1_55_0.7z ]; then
(set -x; mkdir -p _download)
(set -x; curl -o _download/boost_1_55_0.7z -L http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.7z/download)
fi
(set -x; 7z x _download/boost_1_55_0.7z)
(set -x; mv boost_1_55_0 boost)
echo
fi
# fetch and unpack Qt 5.1.2 source
if [ ! -d Qt ]; then
if [ ! -f _download/qt-everywhere-opensource-src-5.2.1.zip ]; then
(set -x; mkdir -p _download)
(set -x; curl -o _download/qt-everywhere-opensource-src-5.2.1.zip -L http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.zip)
fi
(set -x; mkdir Qt)
cd Qt
(set -x; 7z x ../_download/qt-everywhere-opensource-src-5.2.1.zip)
(set -x; mv qt-everywhere-opensource-src-5.2.1 Src)
# patch qmake.conf to use the static CRT
(set -x; sed -i -e 's/-MD/-MT/g' Src/qtbase/mkspecs/win32-msvc2013/qmake.conf)
cd ..
echo
fi
# fetch jom
if [ ! -f "Qt/jom/jom.exe" ]; then
if [ ! -f "_download/jom.zip" ]; then
(set -x; mkdir -p _download)
(set -x; curl -o "_download/jom.zip" -L http://download.qt-project.org/official_releases/jom/jom.zip)
fi
(set -x; mkdir -p Qt/jom)
cd Qt/jom
(set -x; 7z x ../../_download/jom.zip)
cd ../..
echo
fi
# fetch and unpack Lua binaries
if [ ! -d lua ]; then
if [ ! -f _download/lua-5.2.1_Win32_bin.zip ]; then
(set -x; mkdir -p _download)
(set -x; curl -o _download/lua-5.2.1_Win32_bin.zip -L http://sourceforge.net/projects/luabinaries/files/5.2.1/Executables/lua-5.2.1_Win32_bin.zip/download)
fi
(set -x; mkdir lua)
cd lua
(set -x; 7z x ../_download/lua-5.2.1_Win32_bin.zip lua52.exe lua52.dll)
(set -x; mv lua52.exe lua.exe)
cd ..
echo
fi
fi
compile_boost()
{
if [ $platform == "x64" ]; then
addressModel="address-model=64"
else
addressModel=""
fi
if [ ! -d "stage/$platform" ]; then
targets="--with-filesystem --with-system --with-thread --with-date_time --with-regex"
(set -x; ./b2 -j4 --build-type=complete link=static runtime-link=static variant=debug,release threading=multi $addressModel $targets stage)
(set -x; mv stage/lib stage/$platform)
fi
}
if [[ ! $@ ]] || [ $1 == "compile-boost" ]; then
# bootstrap if b2 is missing
cd boost
if [ ! -f "b2.exe" ]; then
(set -x; cmd.exe /c bootstrap.bat)
fi
# compile boost for x86 and x64
platform="x64"; compile_boost
platform="Win32"; compile_boost
cd ..
echo
fi
compile_qt()
{
if [ ! -d $platform ]; then
(set -x; cmd.exe /c "..\\cpp-ethereum\\windows\\compile_qt.bat $platform")
fi
}
if [[ ! $@ ]] || [ $1 == "compile-qt" ]; then
# compile Qt for x86 and x64
cd Qt
platform="x64"; compile_qt
platform="Win32"; compile_qt
cd ..
echo
fi
# finally run MS build
cd cpp-ethereum/windows
cmd.exe /c "compile_ethereum.bat"
cd ..

14
windows/compile_ethereum.bat

@ -0,0 +1,14 @@
@echo off
rem @file compileqt.bat
rem @author Tim Hughes <tim@twistedfury.com>
rem @date 2014
echo on
rem : import VC environment
call "%VS120COMNTOOLS%\VsDevCmd.bat"
rem : build for x64
msbuild /maxcpucount /p:Configuration=Release;Platform=x64 Ethereum.sln
rem : build for Win32
msbuild /maxcpucount /p:Configuration=Release;Platform=Win32 Ethereum.sln

41
windows/compile_qt.bat

@ -0,0 +1,41 @@
@echo off
rem @file compileqt.bat
rem @author Tim Hughes <tim@twistedfury.com>
rem @date 2014
rem : enable use prefix if we want to produce standalone Qt binaries
rem : off by default since this takes longer and duplicates all the headers
set USE_PREFIX=0
rem : echo commands so we can see what's going on
echo on
rem : select platform and toolset from first argument
IF %1%==x64 (set PLATFORM=x64&set TOOLSET=x86_amd64) ELSE (set PLATFORM=Win32&set TOOLSET=x86)
rem : import VC environment vars
call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" %TOOLSET%
rem : assume our root Qt dir is the current dir
set QT=%CD%
rem : create the build folder and add the qtbase/bin folder to the PATH
if not exist %QT%\%PLATFORM% mkdir %QT%\%PLATFORM%
if %USE_PREFIX%==1 (
if not exist %QT%\%PLATFORM%-Build mkdir %QT%\%PLATFORM%-Build
if not exist %QT%\%PLATFORM%\qtbase mkdir %QT%\%PLATFORM%\qtbase
cd %QT%\%PLATFORM%-Build
set QT_PREFIX=-prefix %Qt%\%PLATFORM%\qtbase
set QT_TARGETS=module-qtbase-install_subtargets
) else (
cd %QT%\%PLATFORM%
set QT_PREFIX=
set QT_TARGETS=module-qtbase
)
set PATH=%CD%\qtbase\bin;%PATH%
rem : run Qt configure with desired settings
call %QT%\Src\configure.bat -opensource -confirm-license %QT_PREFIX% -mp -opengl desktop -static -debug-and-release -platform win32-msvc2013 -nomake examples -nomake tests
rem : compile and install module-qtbase
%QT%\jom\jom %QT_TARGETS%

23
windows/include/LibLevelDB/port/port.h

@ -0,0 +1,23 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#ifndef STORAGE_LEVELDB_PORT_PORT_H_
#define STORAGE_LEVELDB_PORT_PORT_H_
#include <string.h>
// Include the appropriate platform specific file below. If you are
// porting to a new platform, see "port_example.h" for documentation
// of what the new port_<platform>.h file must provide.
#if defined(LEVELDB_PLATFORM_POSIX)
# include "port/port_posix.h"
#elif defined(LEVELDB_PLATFORM_CHROMIUM)
# include "port/port_chromium.h"
#elif defined(LEVELDB_PLATFORM_ANDROID)
# include "port/port_android.h"
#elif defined(LEVELDB_PLATFORM_WINDOWS)
# include "port/port_win.h"
#endif
#endif // STORAGE_LEVELDB_PORT_PORT_H_

0
windows/include/LibLevelDB/unistd.h

14
windows/include/LibMiniUPnPc/miniupnpcstrings.h

@ -0,0 +1,14 @@
/* $Id: miniupnpcstrings.h.in,v 1.4 2011/01/04 11:41:53 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2005-2011 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef MINIUPNPCSTRINGS_H_INCLUDED
#define MINIUPNPCSTRINGS_H_INCLUDED
#define OS_STRING "Windows"
#define MINIUPNPC_VERSION_STRING "1.9"
#endif

38
windows/moc.lua

@ -0,0 +1,38 @@
local function quote(x)
return '"' .. x .. '"'
end
local function toForward(x)
return x:gsub('\\', '/')
end
-- arguments are in this order
local cmd = arg[1]
local outFile = arg[2]
local includes = toForward(arg[3])
local defines = arg[4]
local inFile = arg[5]
-- build list of includes
local includes2 = ""
for i in string.gmatch(includes, "[^;]+") do
includes2 = includes2.." -I "..quote(i)
end
includes = includes2;
-- build list of defines
local defines2 = ""
for i in string.gmatch(defines, "[^;]+") do
defines2 = defines2.." -D"..i
end
defines = defines2
-- moc doesn't compile boost correctly, so skip those headers
workarounds=' -DBOOST_MP_CPP_INT_HPP -DBOOST_THREAD_WEK01082003_HPP'
-- build command
cmd = quote(cmd).." -o "..quote(outFile)..includes..defines..workarounds..' '..quote(inFile)
print(cmd)
os.execute(quote(cmd))

2
windows/qt_plugin_import.cpp

@ -1,4 +1,4 @@
// This file is autogenerated by qmake. It imports static plugin classes for
// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables.
#include <QtPlugin>
#include <QtCore/QtPlugin>
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)

21
windows/stdafx.cpp

@ -0,0 +1,21 @@
/*
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 stdafx.cpp
* @author Tim Hughes <tim@twistedfury.com>
* @date 2014
*/

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save