mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -24,3 +24,6 @@ tmp
|
||||
|
||||
# Ignore database directory.
|
||||
db/*.db
|
||||
|
||||
# Ignore customized test/config.js
|
||||
test/config.js
|
||||
|
||||
40
SConstruct
40
SConstruct
@@ -5,7 +5,9 @@
|
||||
import glob
|
||||
import platform
|
||||
|
||||
OSX = bool(platform.mac_ver()[0])
|
||||
OSX = bool(platform.mac_ver()[0])
|
||||
FreeBSD = bool('FreeBSD' == platform.system())
|
||||
Ubuntu = bool('Ubuntu' == platform.dist())
|
||||
|
||||
if OSX:
|
||||
CTAGS = '/usr/bin/ctags'
|
||||
@@ -43,14 +45,38 @@ for dir in ['ripple', 'database', 'json', 'websocketpp']:
|
||||
# Use openssl
|
||||
env.ParseConfig('pkg-config --cflags --libs openssl')
|
||||
|
||||
# The required version of boost is documented in the README file.
|
||||
#
|
||||
# We whitelist platforms where the non -mt version is linked with pthreads.
|
||||
# This can be verified with: ldd libboost_filesystem.*
|
||||
# If a threading library is included the platform can be whitelisted.
|
||||
#
|
||||
# FreeBSD and Ubuntu non-mt libs do link with pthreads.
|
||||
if FreeBSD or Ubuntu:
|
||||
env.Append(
|
||||
LIBS = [
|
||||
'boost_date_time',
|
||||
'boost_filesystem',
|
||||
'boost_program_options',
|
||||
'boost_regex',
|
||||
'boost_system',
|
||||
'boost_thread',
|
||||
]
|
||||
)
|
||||
else:
|
||||
env.Append(
|
||||
LIBS = [
|
||||
'boost_date_time-mt',
|
||||
'boost_filesystem-mt',
|
||||
'boost_program_options-mt',
|
||||
'boost_regex-mt',
|
||||
'boost_system-mt',
|
||||
'boost_thread-mt',
|
||||
]
|
||||
)
|
||||
|
||||
env.Append(
|
||||
LIBS = [
|
||||
'boost_date_time-mt',
|
||||
'boost_filesystem-mt',
|
||||
'boost_program_options-mt',
|
||||
'boost_regex-mt',
|
||||
'boost_system-mt',
|
||||
'boost_thread-mt',
|
||||
'protobuf',
|
||||
'dl', # dynamic linking
|
||||
'z'
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
<ClCompile Include="src\cpp\json\json_reader.cpp" />
|
||||
<ClCompile Include="src\cpp\json\json_value.cpp" />
|
||||
<ClCompile Include="src\cpp\json\json_writer.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\AccountState.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Amount.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Application.cpp" />
|
||||
@@ -127,17 +128,21 @@
|
||||
<ClCompile Include="src\cpp\ripple\main.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\NetworkOPs.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\NicknameState.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OfferCancelTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OfferCreateTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Operation.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OrderBook.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OrderBookDB.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PackedMessage.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ParseSection.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Pathfinder.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PaymentTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Peer.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PeerDoor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PlatRand.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PubKeyCache.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RangeSet.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RegularKeySetTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\rfc1751.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ripple.pb.cc" />
|
||||
<ClCompile Include="src\cpp\ripple\RippleAddress.cpp" />
|
||||
@@ -162,16 +167,18 @@
|
||||
<ClCompile Include="src\cpp\ripple\SNTPClient.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Suppression.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Transaction.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionAction.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionEngine.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionErr.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionFormats.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionMaster.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionMeta.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Transactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TrustSetTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\UniqueNodeList.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\utils.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ValidationCollection.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Wallet.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\WalletAddTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\WSConnection.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\WSDoor.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\base64\base64.cpp" />
|
||||
@@ -191,6 +198,7 @@
|
||||
<ClInclude Include="database\sqlite3.h" />
|
||||
<ClInclude Include="database\sqlite3ext.h" />
|
||||
<ClInclude Include="database\SqliteDatabase.h" />
|
||||
<ClInclude Include="src\cpp\ripple\AccountSetTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\AccountState.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Application.h" />
|
||||
<ClInclude Include="src\cpp\ripple\base58.h" />
|
||||
@@ -223,17 +231,21 @@
|
||||
<ClInclude Include="src\cpp\ripple\NetworkOPs.h" />
|
||||
<ClInclude Include="src\cpp\ripple\NetworkStatus.h" />
|
||||
<ClInclude Include="src\cpp\ripple\NicknameState.h" />
|
||||
<ClInclude Include="src\cpp\ripple\OfferCancelTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\OfferCreateTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Operation.h" />
|
||||
<ClInclude Include="src\cpp\ripple\OrderBook.h" />
|
||||
<ClInclude Include="src\cpp\ripple\OrderBookDB.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PackedMessage.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ParseSection.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Pathfinder.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PaymentTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Peer.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PeerDoor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ProofOfWork.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PubKeyCache.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RangeSet.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RegularKeySetTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\rfc1751.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ripple.pb.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleAddress.h" />
|
||||
@@ -266,6 +278,8 @@
|
||||
<ClInclude Include="src\cpp\ripple\TransactionFormats.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionMaster.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionMeta.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Transactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TrustSetTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\types.h" />
|
||||
<ClInclude Include="src\cpp\ripple\uint256.h" />
|
||||
<ClInclude Include="src\cpp\ripple\UniqueNodeList.h" />
|
||||
@@ -273,6 +287,7 @@
|
||||
<ClInclude Include="src\cpp\ripple\ValidationCollection.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Version.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Wallet.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WalletAddTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WSConnection.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WSDoor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WSHandler.h" />
|
||||
|
||||
@@ -249,9 +249,6 @@
|
||||
<ClCompile Include="src\cpp\ripple\Transaction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionAction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionEngine.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -321,6 +318,30 @@
|
||||
<ClCompile Include="src\cpp\websocketpp\src\sha1\sha1.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Transactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\PaymentTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\WalletAddTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\OfferCancelTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\OfferCreateTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RegularKeySetTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TrustSetTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="util\pugiconfig.hpp">
|
||||
@@ -599,6 +620,30 @@
|
||||
<ClInclude Include="src\cpp\ripple\WSHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Transactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\PaymentTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TrustSetTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RegularKeySetTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\OfferCreateTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\OfferCancelTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\AccountSetTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\WalletAddTransactor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="wallet.xml" />
|
||||
|
||||
20
ripple2010.sln
Normal file
20
ripple2010.sln
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ripple2010", "ripple2010.vcxproj", "{19465545-42EE-42FA-9CC8-F8975F8F1CC7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
317
ripple2010.vcxproj
Normal file
317
ripple2010.vcxproj
Normal file
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.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="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{19465545-42EE-42FA-9CC8-F8975F8F1CC7}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>newcoin</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</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" />
|
||||
</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" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\;..\OpenSSL\include;..\boost_1_52_0;..\protobuf\src\</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\OpenSSL\lib\VC;..\boost_1_52_0\stage\lib;..\protobuf\vsprojects\Debug</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>ssleay32MDd.lib;libeay32MTd.lib;libprotobuf.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<CustomBuild>
|
||||
<Command>c:/code/protoc-2.4.1-win32/protoc -I=C:\code\newcoin --cpp_out=C:\code\newcoin C:\code\newcoin/newcoin.proto</Command>
|
||||
</CustomBuild>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\OpenSSL\include;..\boost_1_47_0;..\protobuf-2.4.1\src</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>..\OpenSSL\lib\VC;..\boost_1_47_0\stage\lib;..\protobuf-2.4.1\vsprojects\Release</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libprotobuf.lib;ssleay32MD.lib;libeay32MD.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\cpp\database\database.cpp" />
|
||||
<ClCompile Include="src\cpp\database\sqlite3.c" />
|
||||
<ClCompile Include="src\cpp\database\SqliteDatabase.cpp" />
|
||||
<ClCompile Include="src\cpp\database\win\windatabase.cpp" />
|
||||
<ClCompile Include="src\cpp\json\json_reader.cpp" />
|
||||
<ClCompile Include="src\cpp\json\json_value.cpp" />
|
||||
<ClCompile Include="src\cpp\json\json_writer.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\AccountState.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Amount.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Application.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\BitcoinUtil.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\CallRPC.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\CanonicalTXSet.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Config.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ConnectionPool.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Contract.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\DBInit.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\DeterministicKeys.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ECIES.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\FieldNames.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\HashedObject.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\HTTPRequest.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\HttpsClient.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\InstanceCounter.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Interpreter.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\JobQueue.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Ledger.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerAcquire.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerConsensus.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerEntrySet.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerFormats.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerHistory.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerMaster.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerProposal.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\LedgerTiming.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Log.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\main.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\NetworkOPs.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\NicknameState.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OfferCancelTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OfferCreateTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Operation.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OrderBook.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\OrderBookDB.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PackedMessage.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ParseSection.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Pathfinder.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PaymentTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Peer.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PeerDoor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PlatRand.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ProofOfWork.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\PubKeyCache.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RangeSet.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RegularKeySetTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\rfc1751.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ripple.pb.cc" />
|
||||
<ClCompile Include="src\cpp\ripple\RippleAddress.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RippleCalc.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RippleLines.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RippleState.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\rpc.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RPCDoor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RPCHandler.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\RPCServer.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ScriptData.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SerializedLedger.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SerializedObject.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SerializedTransaction.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SerializedTypes.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SerializedValidation.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Serializer.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SHAMap.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SHAMapDiff.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SHAMapNodes.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SHAMapSync.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\SNTPClient.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Suppression.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Transaction.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionEngine.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionErr.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionFormats.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionMaster.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TransactionMeta.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Transactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\TrustSetTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\UniqueNodeList.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\utils.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\ValidationCollection.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\Wallet.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\WalletAddTransactor.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\WSConnection.cpp" />
|
||||
<ClCompile Include="src\cpp\ripple\WSDoor.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\base64\base64.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\md5\md5.c" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\messages\data.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\network_utilities.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\processors\hybi_header.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\processors\hybi_util.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\rng\blank_rng.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\rng\boost_rng.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\sha1\sha1.cpp" />
|
||||
<ClCompile Include="src\cpp\websocketpp\src\uri.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="bitcoinUtil.h" />
|
||||
<ClInclude Include="database\database.h" />
|
||||
<ClInclude Include="database\sqlite3.h" />
|
||||
<ClInclude Include="database\sqlite3ext.h" />
|
||||
<ClInclude Include="database\SqliteDatabase.h" />
|
||||
<ClInclude Include="src\cpp\ripple\AccountState.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Application.h" />
|
||||
<ClInclude Include="src\cpp\ripple\base58.h" />
|
||||
<ClInclude Include="src\cpp\ripple\bignum.h" />
|
||||
<ClInclude Include="src\cpp\ripple\BitcoinUtil.h" />
|
||||
<ClInclude Include="src\cpp\ripple\CallRPC.h" />
|
||||
<ClInclude Include="src\cpp\ripple\CanonicalTXSet.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Config.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ConnectionPool.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Contract.h" />
|
||||
<ClInclude Include="src\cpp\ripple\FieldNames.h" />
|
||||
<ClInclude Include="src\cpp\ripple\HashedObject.h" />
|
||||
<ClInclude Include="src\cpp\ripple\HashPrefixes.h" />
|
||||
<ClInclude Include="src\cpp\ripple\HTTPRequest.h" />
|
||||
<ClInclude Include="src\cpp\ripple\HttpsClient.h" />
|
||||
<ClInclude Include="src\cpp\ripple\InstanceCounter.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Interpreter.h" />
|
||||
<ClInclude Include="src\cpp\ripple\JobQueue.h" />
|
||||
<ClInclude Include="src\cpp\ripple\key.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Ledger.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerAcquire.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerConsensus.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerEntrySet.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerFormats.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerHistory.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerMaster.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerProposal.h" />
|
||||
<ClInclude Include="src\cpp\ripple\LedgerTiming.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Log.h" />
|
||||
<ClInclude Include="src\cpp\ripple\NetworkOPs.h" />
|
||||
<ClInclude Include="src\cpp\ripple\NetworkStatus.h" />
|
||||
<ClInclude Include="src\cpp\ripple\NicknameState.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Operation.h" />
|
||||
<ClInclude Include="src\cpp\ripple\OrderBook.h" />
|
||||
<ClInclude Include="src\cpp\ripple\OrderBookDB.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PackedMessage.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ParseSection.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Pathfinder.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Peer.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PeerDoor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ProofOfWork.h" />
|
||||
<ClInclude Include="src\cpp\ripple\PubKeyCache.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RangeSet.h" />
|
||||
<ClInclude Include="src\cpp\ripple\rfc1751.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ripple.pb.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleAddress.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleCalc.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleLines.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleState.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPC.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPCCommands.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPCDoor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPCHandler.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPCServer.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ScopedLock.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ScriptData.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SecureAllocator.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SerializedLedger.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SerializedObject.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SerializedTransaction.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SerializedTypes.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SerializedValidation.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SerializeProto.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Serializer.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SHAMap.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SHAMapSync.h" />
|
||||
<ClInclude Include="src\cpp\ripple\SNTPClient.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Suppression.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TaggedCache.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Transaction.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionEngine.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionErr.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionFormats.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionMaster.h" />
|
||||
<ClInclude Include="src\cpp\ripple\TransactionMeta.h" />
|
||||
<ClInclude Include="src\cpp\ripple\types.h" />
|
||||
<ClInclude Include="src\cpp\ripple\uint256.h" />
|
||||
<ClInclude Include="src\cpp\ripple\UniqueNodeList.h" />
|
||||
<ClInclude Include="src\cpp\ripple\utils.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ValidationCollection.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Version.h" />
|
||||
<ClInclude Include="src\cpp\ripple\Wallet.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WSConnection.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WSDoor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\WSHandler.h" />
|
||||
<ClInclude Include="util\pugiconfig.hpp" />
|
||||
<ClInclude Include="util\pugixml.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="html\newcoin.html">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="newcoind.cfg" />
|
||||
<None Include="README" />
|
||||
<None Include="SConstruct" />
|
||||
<CustomBuild Include="src\cpp\ripple\ripple.proto">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/code/protobuf/protoc -I=..\newcoin --cpp_out=\code\newcoin\ ..\newcoin/src/cpp/ripple/ripple.proto</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\code\newcoin\src\ripple.pb.h</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="test\buster.js" />
|
||||
<None Include="test\server.js" />
|
||||
<None Include="test\standalone-test.js" />
|
||||
<None Include="test\utils.js" />
|
||||
<None Include="validators.txt" />
|
||||
<None Include="wallet.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
644
ripple2010.vcxproj.filters
Normal file
644
ripple2010.vcxproj.filters
Normal file
@@ -0,0 +1,644 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\util">
|
||||
<UniqueIdentifier>{54608e0e-4ac4-44d6-af96-0c278457ac6f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\json">
|
||||
<UniqueIdentifier>{c642219d-cace-47c1-828a-58ba570da63a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\json">
|
||||
<UniqueIdentifier>{c717b139-5eba-454b-8888-9bf54ce0a652}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="html">
|
||||
<UniqueIdentifier>{77d2a621-b503-4ce4-aee8-ef0b337c4ee2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\database">
|
||||
<UniqueIdentifier>{60c3631e-8855-4a61-bdd3-9892d96242d5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\websocketpp">
|
||||
<UniqueIdentifier>{92775c5f-dc9f-4a97-a9a6-6d4bd4e424b4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\cpp\database\database.cpp">
|
||||
<Filter>Source Files\database</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\database\SqliteDatabase.cpp">
|
||||
<Filter>Source Files\database</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\database\win\windatabase.cpp">
|
||||
<Filter>Source Files\database</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\json\json_reader.cpp">
|
||||
<Filter>Source Files\json</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\json\json_value.cpp">
|
||||
<Filter>Source Files\json</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\json\json_writer.cpp">
|
||||
<Filter>Source Files\json</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\AccountState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Amount.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Application.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\BitcoinUtil.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\CallRPC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\CanonicalTXSet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Config.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ConnectionPool.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Contract.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\DBInit.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\DeterministicKeys.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ECIES.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\FieldNames.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\HashedObject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\HTTPRequest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\HttpsClient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\InstanceCounter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Interpreter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\JobQueue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Ledger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerAcquire.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerConsensus.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerEntrySet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerFormats.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerHistory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerMaster.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerProposal.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LedgerTiming.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Log.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\NetworkOPs.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\NicknameState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Operation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\OrderBook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\OrderBookDB.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\PackedMessage.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ParseSection.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Pathfinder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Peer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\PeerDoor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\PlatRand.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\PubKeyCache.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RangeSet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\rfc1751.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RippleAddress.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RippleCalc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RippleLines.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RippleState.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\rpc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RPCDoor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RPCHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RPCServer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ScriptData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SerializedLedger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SerializedObject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SerializedTransaction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SerializedTypes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SerializedValidation.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Serializer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SHAMap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SHAMapDiff.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SHAMapNodes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SHAMapSync.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\SNTPClient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Suppression.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Transaction.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionEngine.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionErr.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionFormats.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionMaster.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TransactionMeta.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\UniqueNodeList.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ValidationCollection.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Wallet.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\WSConnection.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\WSDoor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ripple.pb.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\database\sqlite3.c">
|
||||
<Filter>Source Files\database</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\sha1\sha1.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\network_utilities.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\uri.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\base64\base64.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\md5\md5.c">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\messages\data.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\processors\hybi_header.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\processors\hybi_util.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\rng\blank_rng.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\websocketpp\src\rng\boost_rng.cpp">
|
||||
<Filter>Source Files\websocketpp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\AccountSetTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\OfferCancelTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\OfferCreateTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\PaymentTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ProofOfWork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\RegularKeySetTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\Transactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\TrustSetTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\WalletAddTransactor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="util\pugiconfig.hpp">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\pugixml.hpp">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="bitcoinUtil.h">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="database\database.h">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="database\SqliteDatabase.h">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="database\sqlite3.h">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="database\sqlite3ext.h">
|
||||
<Filter>Header Files\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\AccountState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Application.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\base58.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\bignum.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\BitcoinUtil.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\CallRPC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\CanonicalTXSet.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ConnectionPool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Contract.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\FieldNames.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\HashedObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\HashPrefixes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\HTTPRequest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\HttpsClient.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\InstanceCounter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Interpreter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\JobQueue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\key.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Ledger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerAcquire.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerConsensus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerEntrySet.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerFormats.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerHistory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerMaster.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerProposal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LedgerTiming.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\NetworkOPs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\NetworkStatus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\NicknameState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Operation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\OrderBook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\OrderBookDB.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\PackedMessage.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ParseSection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Pathfinder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Peer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\PeerDoor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ProofOfWork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\PubKeyCache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RangeSet.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\rfc1751.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ripple.pb.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RippleAddress.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RippleCalc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RippleLines.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RippleState.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RPC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RPCCommands.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RPCDoor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RPCHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\RPCServer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ScopedLock.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ScriptData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SecureAllocator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SerializedLedger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SerializedObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SerializedTransaction.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SerializedTypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SerializedValidation.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SerializeProto.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Serializer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SHAMap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SHAMapSync.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\SNTPClient.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Suppression.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TaggedCache.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Transaction.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TransactionEngine.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TransactionErr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TransactionFormats.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TransactionMaster.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\TransactionMeta.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\types.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\uint256.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\UniqueNodeList.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ValidationCollection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\Wallet.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\WSConnection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\WSDoor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\WSHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="wallet.xml" />
|
||||
<None Include="html\newcoin.html">
|
||||
<Filter>html</Filter>
|
||||
</None>
|
||||
<None Include="SConstruct" />
|
||||
<None Include="newcoind.cfg" />
|
||||
<None Include="validators.txt" />
|
||||
<None Include="README" />
|
||||
<None Include="test\buster.js" />
|
||||
<None Include="test\server.js" />
|
||||
<None Include="test\standalone-test.js" />
|
||||
<None Include="test\utils.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="src\cpp\ripple\ripple.proto" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
119
src/cpp/ripple/AccountSetTransactor.cpp
Normal file
119
src/cpp/ripple/AccountSetTransactor.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include "AccountSetTransactor.h"
|
||||
|
||||
TER AccountSetTransactor::doApply()
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet>";
|
||||
|
||||
//
|
||||
// EmailHash
|
||||
//
|
||||
|
||||
if (mTxn.isFieldPresent(sfEmailHash))
|
||||
{
|
||||
uint128 uHash = mTxn.getFieldH128(sfEmailHash);
|
||||
|
||||
if (!uHash)
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: unset email hash";
|
||||
|
||||
mTxnAccount->makeFieldAbsent(sfEmailHash);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: set email hash";
|
||||
|
||||
mTxnAccount->setFieldH128(sfEmailHash, uHash);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// WalletLocator
|
||||
//
|
||||
|
||||
if (mTxn.isFieldPresent(sfWalletLocator))
|
||||
{
|
||||
uint256 uHash = mTxn.getFieldH256(sfWalletLocator);
|
||||
|
||||
if (!uHash)
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: unset wallet locator";
|
||||
|
||||
mTxnAccount->makeFieldAbsent(sfEmailHash);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: set wallet locator";
|
||||
|
||||
mTxnAccount->setFieldH256(sfWalletLocator, uHash);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// MessageKey
|
||||
//
|
||||
|
||||
if (!mTxn.isFieldPresent(sfMessageKey))
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: set message key";
|
||||
|
||||
mTxnAccount->setFieldVL(sfMessageKey, mTxn.getFieldVL(sfMessageKey));
|
||||
}
|
||||
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
|
||||
if (mTxn.isFieldPresent(sfDomain))
|
||||
{
|
||||
std::vector<unsigned char> vucDomain = mTxn.getFieldVL(sfDomain);
|
||||
|
||||
if (vucDomain.empty())
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: unset domain";
|
||||
|
||||
mTxnAccount->makeFieldAbsent(sfDomain);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: set domain";
|
||||
|
||||
mTxnAccount->setFieldVL(sfDomain, vucDomain);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TransferRate
|
||||
//
|
||||
|
||||
if (mTxn.isFieldPresent(sfTransferRate))
|
||||
{
|
||||
uint32 uRate = mTxn.getFieldU32(sfTransferRate);
|
||||
|
||||
if (!uRate || uRate == QUALITY_ONE)
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: unset transfer rate";
|
||||
|
||||
mTxnAccount->makeFieldAbsent(sfTransferRate);
|
||||
}
|
||||
else if (uRate > QUALITY_ONE)
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: set transfer rate";
|
||||
|
||||
mTxnAccount->setFieldU32(sfTransferRate, uRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "doAccountSet: bad transfer rate";
|
||||
|
||||
return temBAD_TRANSFER_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsINFO) << "doAccountSet<";
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
9
src/cpp/ripple/AccountSetTransactor.h
Normal file
9
src/cpp/ripple/AccountSetTransactor.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "Transactor.h"
|
||||
|
||||
class AccountSetTransactor : public Transactor
|
||||
{
|
||||
public:
|
||||
AccountSetTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
|
||||
TER doApply();
|
||||
};
|
||||
@@ -33,12 +33,12 @@ public:
|
||||
|
||||
bool bHaveAuthorizedKey()
|
||||
{
|
||||
return mLedgerEntry->isFieldPresent(sfAuthorizedKey);
|
||||
return mLedgerEntry->isFieldPresent(sfRegularKey);
|
||||
}
|
||||
|
||||
RippleAddress getAuthorizedKey()
|
||||
{
|
||||
return mLedgerEntry->getFieldAccount(sfAuthorizedKey);
|
||||
return mLedgerEntry->getFieldAccount(sfRegularKey);
|
||||
}
|
||||
|
||||
STAmount getBalance() const { return mLedgerEntry->getFieldAmount(sfBalance); }
|
||||
|
||||
@@ -28,8 +28,16 @@ SField sfIndex(STI_HASH256, 258, "index");
|
||||
|
||||
static int initFields()
|
||||
{
|
||||
sfTxnSignature.notSigningField(); sfTxnSignatures.notSigningField();
|
||||
sfTxnSignature.notSigningField();
|
||||
sfTxnSignatures.notSigningField();
|
||||
sfSignature.notSigningField();
|
||||
|
||||
sfIndexes.setMeta(SField::sMD_Never);
|
||||
sfPreviousTxnID.setMeta(SField::sMD_Never);
|
||||
sfPreviousTxnLgrSeq.setMeta(SField::sMD_Never);
|
||||
sfLedgerEntryType.setMeta(SField::sMD_Never);
|
||||
sfRootIndex.setMeta(SField::sMD_Always);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static const int f = initFields();
|
||||
|
||||
@@ -30,7 +30,8 @@ enum SOE_Flags
|
||||
{
|
||||
SOE_INVALID = -1,
|
||||
SOE_REQUIRED = 0, // required
|
||||
SOE_OPTIONAL = 1, // optional
|
||||
SOE_OPTIONAL = 1, // optional, may be present with default value
|
||||
SOE_DEFAULT = 2, // optional, if present, must not have default value
|
||||
};
|
||||
|
||||
class SField
|
||||
@@ -39,6 +40,14 @@ public:
|
||||
typedef const SField& ref;
|
||||
typedef SField const * ptr;
|
||||
|
||||
static const int sMD_Never = 0x00;
|
||||
static const int sMD_ChangeOrig = 0x01; // original value when it changes
|
||||
static const int sMD_ChangeNew = 0x02; // new value when it changes
|
||||
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
|
||||
static const int sMD_Create = 0x08; // value when it's created
|
||||
static const int sMD_Always = 0x10; // value when node containing it is affected at all
|
||||
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal;
|
||||
|
||||
protected:
|
||||
static std::map<int, ptr> codeToField;
|
||||
static boost::mutex mapMutex;
|
||||
@@ -51,23 +60,25 @@ public:
|
||||
const SerializedTypeID fieldType; // STI_*
|
||||
const int fieldValue; // Code number for protocol
|
||||
std::string fieldName;
|
||||
int fieldMeta;
|
||||
bool signingField;
|
||||
|
||||
SField(int fc, SerializedTypeID tid, int fv, const char* fn) :
|
||||
fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn), signingField(true)
|
||||
fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn), fieldMeta(sMD_Default), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
codeToField[fieldCode] = this;
|
||||
}
|
||||
|
||||
SField(SerializedTypeID tid, int fv, const char *fn) :
|
||||
fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn), signingField(true)
|
||||
fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn),
|
||||
fieldMeta(sMD_Default), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
codeToField[fieldCode] = this;
|
||||
}
|
||||
|
||||
SField(int fc) : fieldCode(fc), fieldType(STI_UNKNOWN), fieldValue(0) { ; }
|
||||
SField(int fc) : fieldCode(fc), fieldType(STI_UNKNOWN), fieldValue(0), fieldMeta(sMD_Never) { ; }
|
||||
|
||||
~SField();
|
||||
|
||||
@@ -85,8 +96,10 @@ public:
|
||||
bool isBinary() const { return fieldValue < 256; }
|
||||
bool isDiscardable() const { return fieldValue > 256; }
|
||||
|
||||
bool isSigningField() const { return signingField; }
|
||||
void notSigningField() { signingField = false; }
|
||||
bool isSigningField() const { return signingField; }
|
||||
void notSigningField() { signingField = false; }
|
||||
bool shouldMeta(int c) const { return (fieldMeta & c) != 0; }
|
||||
void setMeta(int c) { fieldMeta = c; }
|
||||
|
||||
bool shouldInclude(bool withSigningField) const
|
||||
{ return (fieldValue < 256) && (withSigningField || signingField); }
|
||||
|
||||
@@ -44,6 +44,7 @@ DEFINE_INSTANCE(Ledger);
|
||||
class Ledger : public boost::enable_shared_from_this<Ledger>, public IS_INSTANCE(Ledger)
|
||||
{ // The basic Ledger structure, can be opened, closed, or synching
|
||||
friend class TransactionEngine;
|
||||
friend class Transactor;
|
||||
public:
|
||||
typedef boost::shared_ptr<Ledger> pointer;
|
||||
typedef const boost::shared_ptr<Ledger>& ref;
|
||||
|
||||
@@ -275,7 +275,10 @@ SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::ref ledger,
|
||||
if (it != mEntries.end())
|
||||
{
|
||||
if (it->second.mAction == taaDELETE)
|
||||
{
|
||||
cLog(lsFATAL) << "Trying to thread to deleted node";
|
||||
return SLE::pointer();
|
||||
}
|
||||
if (it->second.mAction == taaCACHED)
|
||||
it->second.mAction = taaMODIFY;
|
||||
if (it->second.mSeq != mSeq)
|
||||
@@ -288,7 +291,10 @@ SLE::pointer LedgerEntrySet::getForMod(const uint256& node, Ledger::ref ledger,
|
||||
|
||||
boost::unordered_map<uint256, SLE::pointer>::iterator me = newMods.find(node);
|
||||
if (me != newMods.end())
|
||||
{
|
||||
assert(me->second);
|
||||
return me->second;
|
||||
}
|
||||
|
||||
SLE::pointer ret = ledger->getSLE(node);
|
||||
if (ret)
|
||||
@@ -306,6 +312,7 @@ bool LedgerEntrySet::threadTx(const RippleAddress& threadTo, Ledger::ref ledger,
|
||||
SLE::pointer sle = getForMod(Ledger::getAccountRootIndex(threadTo.getAccountID()), ledger, newMods);
|
||||
if (!sle)
|
||||
{
|
||||
cLog(lsFATAL) << "Threading to non-existent account: " << threadTo.humanAccountID();
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
@@ -400,59 +407,66 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
mSet.setAffectedNode(it.first, *type, nodeType);
|
||||
|
||||
if (type == &sfDeletedNode)
|
||||
{
|
||||
{ // nodes was deleted
|
||||
assert(origNode);
|
||||
assert(curNode);
|
||||
threadOwners(origNode, mLedger, newMod);
|
||||
threadOwners(origNode, mLedger, newMod); // thread transaction to owners
|
||||
|
||||
STObject mods(sfPreviousFields);
|
||||
STObject finals(sfFinalFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *curNode)
|
||||
{ // save non-default values
|
||||
if (!obj.isDefault() && (obj.getFName() != sfLedgerEntryType))
|
||||
finals.addObject(obj);
|
||||
}
|
||||
if (!finals.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(finals);
|
||||
}
|
||||
|
||||
if ((type == &sfDeletedNode || type == &sfModifiedNode))
|
||||
{
|
||||
STObject mods(sfPreviousFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *origNode)
|
||||
{ // search the original node for values saved on modify
|
||||
if (!obj.isDefault() && (obj.getFName() != sfLedgerEntryType) && !curNode->hasMatchingEntry(obj))
|
||||
{
|
||||
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
|
||||
mods.addObject(obj);
|
||||
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_DeleteFinal))
|
||||
finals.addObject(obj);
|
||||
}
|
||||
if (!mods.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(mods);
|
||||
if (!finals.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(finals);
|
||||
}
|
||||
else if (type == &sfModifiedNode)
|
||||
{
|
||||
if (curNode->isThreadedType()) // thread transaction to node it modified
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
|
||||
if (type == &sfCreatedNode) // if created, thread to owner(s)
|
||||
STObject mods(sfPreviousFields);
|
||||
STObject finals(sfFinalFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *origNode)
|
||||
{ // search the original node for values saved on modify
|
||||
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
|
||||
mods.addObject(obj);
|
||||
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_ChangeNew))
|
||||
finals.addObject(obj);
|
||||
}
|
||||
if (!mods.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(mods);
|
||||
if (!finals.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(finals);
|
||||
}
|
||||
else if (type == &sfCreatedNode) // if created, thread to owner(s)
|
||||
{
|
||||
assert(!origNode);
|
||||
threadOwners(curNode, mLedger, newMod);
|
||||
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
STObject news(sfNewFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *curNode)
|
||||
{ // save non-default values
|
||||
if (!obj.isDefault() && (obj.getFName() != sfLedgerEntryType))
|
||||
if (!obj.isDefault() && obj.getFName().shouldMeta(SField::sMD_Create | SField::sMD_Always))
|
||||
news.addObject(obj);
|
||||
}
|
||||
if (!news.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(news);
|
||||
}
|
||||
|
||||
if ((type == &sfCreatedNode) || (type == &sfModifiedNode))
|
||||
{
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
}
|
||||
}
|
||||
|
||||
// add any new modified nodes to the modification set
|
||||
for (boost::unordered_map<uint256, SLE::pointer>::iterator it = newMod.begin(), end = newMod.end();
|
||||
it != end; ++it)
|
||||
entryModify(it->second);
|
||||
typedef std::pair<const uint256, SLE::pointer> u256_sle_pair;
|
||||
BOOST_FOREACH(u256_sle_pair& it, newMod)
|
||||
entryModify(it.second);
|
||||
|
||||
mSet.addRaw(s, result);
|
||||
cLog(lsTRACE) << "Metadata:" << mSet.getJson(0);
|
||||
@@ -476,6 +490,7 @@ TER LedgerEntrySet::dirAdd(
|
||||
{
|
||||
// No root, make it.
|
||||
sleRoot = entryCreate(ltDIR_NODE, uRootIndex);
|
||||
sleRoot->setFieldH256(sfRootIndex, uRootIndex);
|
||||
|
||||
sleNode = sleRoot;
|
||||
uNodeDir = 0;
|
||||
@@ -536,6 +551,7 @@ TER LedgerEntrySet::dirAdd(
|
||||
|
||||
// Create the new node.
|
||||
sleNode = entryCreate(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
|
||||
sleNode->setFieldH256(sfRootIndex, uRootIndex);
|
||||
svIndexes = STVector256();
|
||||
}
|
||||
}
|
||||
@@ -1020,14 +1036,21 @@ void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uRece
|
||||
uint256 uIndex = Ledger::getRippleStateIndex(uSenderID, uReceiverID, saAmount.getCurrency());
|
||||
SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, uIndex);
|
||||
|
||||
assert(!!uSenderID && uSenderID != ACCOUNT_ONE);
|
||||
assert(!!uReceiverID && uReceiverID != ACCOUNT_ONE);
|
||||
|
||||
if (!sleRippleState)
|
||||
{
|
||||
cLog(lsDEBUG) << "rippleCredit: Creating ripple line: " << uIndex.ToString();
|
||||
|
||||
STAmount saBalance = saAmount;
|
||||
|
||||
saBalance.setIssuer(ACCOUNT_ONE);
|
||||
|
||||
cLog(lsDEBUG) << boost::str(boost::format("rippleCredit: create line: %s (%s) -> %s : %s")
|
||||
% RippleAddress::createHumanAccountID(uSenderID)
|
||||
% saBalance.getFullText()
|
||||
% RippleAddress::createHumanAccountID(uReceiverID)
|
||||
% saAmount.getFullText());
|
||||
|
||||
sleRippleState = entryCreate(ltRIPPLE_STATE, uIndex);
|
||||
|
||||
if (!bFlipped)
|
||||
@@ -1044,6 +1067,12 @@ void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uRece
|
||||
if (!bFlipped)
|
||||
saBalance.negate(); // Put balance in low terms.
|
||||
|
||||
cLog(lsDEBUG) << boost::str(boost::format("rippleCredit> %s (%s) -> %s : %s")
|
||||
% RippleAddress::createHumanAccountID(uSenderID)
|
||||
% saBalance.getFullText()
|
||||
% RippleAddress::createHumanAccountID(uReceiverID)
|
||||
% saAmount.getFullText());
|
||||
|
||||
saBalance += saAmount;
|
||||
|
||||
if (!bFlipped)
|
||||
@@ -1065,10 +1094,10 @@ STAmount LedgerEntrySet::rippleSend(const uint160& uSenderID, const uint160& uRe
|
||||
|
||||
assert(!!uSenderID && !!uReceiverID);
|
||||
|
||||
if (uSenderID == uIssuerID || uReceiverID == uIssuerID)
|
||||
if (uSenderID == uIssuerID || uReceiverID == uIssuerID || uIssuerID == ACCOUNT_ONE)
|
||||
{
|
||||
// Direct send: redeeming IOUs and/or sending own IOUs.
|
||||
rippleCredit(uSenderID, uReceiverID, saAmount);
|
||||
rippleCredit(uSenderID, uReceiverID, saAmount, false);
|
||||
|
||||
saActual = saAmount;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ static bool LEFInit()
|
||||
<< SOElement(sfBalance, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement(sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
<< SOElement(sfAuthorizedKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfRegularKey, SOE_OPTIONAL)
|
||||
<< SOElement(sfEmailHash, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletLocator, SOE_OPTIONAL)
|
||||
<< SOElement(sfWalletSize, SOE_OPTIONAL)
|
||||
@@ -39,14 +39,15 @@ static bool LEFInit()
|
||||
<< SOElement(sfOwner, SOE_REQUIRED)
|
||||
<< SOElement(sfExpiration, SOE_REQUIRED)
|
||||
<< SOElement(sfBondAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfCreateCode, SOE_REQUIRED)
|
||||
<< SOElement(sfFundCode, SOE_REQUIRED)
|
||||
<< SOElement(sfRemoveCode, SOE_REQUIRED)
|
||||
<< SOElement(sfExpireCode, SOE_REQUIRED)
|
||||
<< SOElement(sfCreateCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfFundCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfRemoveCode, SOE_OPTIONAL)
|
||||
<< SOElement(sfExpireCode, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
DECLARE_LEF(DirectoryNode, ltDIR_NODE)
|
||||
<< SOElement(sfIndexes, SOE_REQUIRED)
|
||||
<< SOElement(sfRootIndex, SOE_REQUIRED)
|
||||
<< SOElement(sfIndexNext, SOE_OPTIONAL)
|
||||
<< SOElement(sfIndexPrevious, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
@@ -1006,8 +1006,8 @@ void NetworkOPs::pubProposedTransaction(Ledger::ref lpCurrent, const SerializedT
|
||||
ispListener->send(jvObj);
|
||||
}
|
||||
}
|
||||
|
||||
pubAccountTransaction(lpCurrent,stTxn,terResult,false);
|
||||
TransactionMetaSet::pointer ret;
|
||||
pubAccountTransaction(lpCurrent,stTxn,terResult,false,ret);
|
||||
}
|
||||
|
||||
void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
|
||||
@@ -1051,7 +1051,10 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
|
||||
// XXX Need to give failures too.
|
||||
TER terResult = tesSUCCESS;
|
||||
|
||||
pubAcceptedTransaction(lpAccepted, *stTxn, terResult);
|
||||
SerializerIterator it(item->peekSerializer());
|
||||
|
||||
TransactionMetaSet::pointer meta = boost::make_shared<TransactionMetaSet>(stTxn->getTransactionID(), lpAccepted->getLedgerSeq(), it.getVL());
|
||||
pubAcceptedTransaction(lpAccepted, *stTxn, terResult,meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1087,7 @@ Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, TER terRes
|
||||
return jvObj;
|
||||
}
|
||||
|
||||
void NetworkOPs::pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult)
|
||||
void NetworkOPs::pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta)
|
||||
{
|
||||
Json::Value jvObj = transJson(stTxn, terResult, true, lpCurrent, "transaction");
|
||||
|
||||
@@ -1101,11 +1104,11 @@ void NetworkOPs::pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedT
|
||||
}
|
||||
}
|
||||
|
||||
pubAccountTransaction(lpCurrent,stTxn,terResult,true);
|
||||
pubAccountTransaction(lpCurrent,stTxn,terResult,true,meta);
|
||||
}
|
||||
|
||||
|
||||
void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, bool bAccepted)
|
||||
void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, bool bAccepted,TransactionMetaSet::pointer& meta)
|
||||
{
|
||||
boost::unordered_set<InfoSub*> notify;
|
||||
|
||||
|
||||
@@ -107,8 +107,8 @@ protected:
|
||||
|
||||
Json::Value pubBootstrapAccountInfo(Ledger::ref lpAccepted, const RippleAddress& naAccountID);
|
||||
|
||||
void pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult);
|
||||
void pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,bool accepted);
|
||||
void pubAcceptedTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,TransactionMetaSet::pointer& meta);
|
||||
void pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult,bool accepted,TransactionMetaSet::pointer& meta);
|
||||
std::map<RippleAddress,bool> getAffectedAccounts(const SerializedTransaction& stTxn);
|
||||
|
||||
public:
|
||||
|
||||
41
src/cpp/ripple/OfferCancelTransactor.cpp
Normal file
41
src/cpp/ripple/OfferCancelTransactor.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "OfferCancelTransactor.h"
|
||||
#include "Log.h"
|
||||
|
||||
TER OfferCancelTransactor::doApply()
|
||||
{
|
||||
TER terResult;
|
||||
const uint32 uOfferSequence = mTxn.getFieldU32(sfOfferSequence);
|
||||
const uint32 uAccountSequenceNext = mTxnAccount->getFieldU32(sfSequence);
|
||||
|
||||
Log(lsDEBUG) << "doOfferCancel: uAccountSequenceNext=" << uAccountSequenceNext << " uOfferSequence=" << uOfferSequence;
|
||||
|
||||
if (!uOfferSequence || uAccountSequenceNext-1 <= uOfferSequence)
|
||||
{
|
||||
Log(lsINFO) << "doOfferCancel: uAccountSequenceNext=" << uAccountSequenceNext << " uOfferSequence=" << uOfferSequence;
|
||||
|
||||
terResult = temBAD_SEQUENCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint256 uOfferIndex = Ledger::getOfferIndex(mTxnAccountID, uOfferSequence);
|
||||
SLE::pointer sleOffer = mEngine->entryCache(ltOFFER, uOfferIndex);
|
||||
|
||||
if (sleOffer)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCancel: uOfferSequence=" << uOfferSequence;
|
||||
|
||||
terResult = mEngine->getNodes().offerDelete(sleOffer, uOfferIndex, mTxnAccountID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCancel: offer not found: "
|
||||
<< RippleAddress::createHumanAccountID(mTxnAccountID)
|
||||
<< " : " << uOfferSequence
|
||||
<< " : " << uOfferIndex.ToString();
|
||||
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
9
src/cpp/ripple/OfferCancelTransactor.h
Normal file
9
src/cpp/ripple/OfferCancelTransactor.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "Transactor.h"
|
||||
|
||||
class OfferCancelTransactor : public Transactor
|
||||
{
|
||||
public:
|
||||
OfferCancelTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
|
||||
TER doApply();
|
||||
};
|
||||
440
src/cpp/ripple/OfferCreateTransactor.cpp
Normal file
440
src/cpp/ripple/OfferCreateTransactor.cpp
Normal file
@@ -0,0 +1,440 @@
|
||||
#include "OfferCreateTransactor.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// Take as much as possible. Adjusts account balances. Charges fees on top to taker.
|
||||
// --> uBookBase: The order book to take against.
|
||||
// --> saTakerPays: What the taker offers (w/ issuer)
|
||||
// --> saTakerGets: What the taker wanted (w/ issuer)
|
||||
// <-- saTakerPaid: What taker paid not including fees. To reduce an offer.
|
||||
// <-- saTakerGot: What taker got not including fees. To reduce an offer.
|
||||
// <-- terResult: tesSUCCESS or terNO_ACCOUNT
|
||||
// XXX: Fees should be paid by the source of the currency.
|
||||
TER OfferCreateTransactor::takeOffers(
|
||||
bool bPassive,
|
||||
const uint256& uBookBase,
|
||||
const uint160& uTakerAccountID,
|
||||
const SLE::pointer& sleTakerAccount,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
STAmount& saTakerPaid,
|
||||
STAmount& saTakerGot)
|
||||
{
|
||||
assert(saTakerPays && saTakerGets);
|
||||
|
||||
Log(lsINFO) << "takeOffers: against book: " << uBookBase.ToString();
|
||||
|
||||
uint256 uTipIndex = uBookBase;
|
||||
const uint256 uBookEnd = Ledger::getQualityNext(uBookBase);
|
||||
const uint64 uTakeQuality = STAmount::getRate(saTakerGets, saTakerPays);
|
||||
const uint160 uTakerPaysAccountID = saTakerPays.getIssuer();
|
||||
const uint160 uTakerGetsAccountID = saTakerGets.getIssuer();
|
||||
TER terResult = temUNCERTAIN;
|
||||
|
||||
boost::unordered_set<uint256> usOfferUnfundedFound; // Offers found unfunded.
|
||||
boost::unordered_set<uint256> usOfferUnfundedBecame; // Offers that became unfunded.
|
||||
boost::unordered_set<uint160> usAccountTouched; // Accounts touched.
|
||||
|
||||
saTakerPaid = STAmount(saTakerPays.getCurrency(), saTakerPays.getIssuer());
|
||||
saTakerGot = STAmount(saTakerGets.getCurrency(), saTakerGets.getIssuer());
|
||||
|
||||
while (temUNCERTAIN == terResult)
|
||||
{
|
||||
SLE::pointer sleOfferDir;
|
||||
uint64 uTipQuality;
|
||||
|
||||
// Figure out next offer to take, if needed.
|
||||
if (saTakerGets != saTakerGot && saTakerPays != saTakerPaid)
|
||||
{
|
||||
// Taker, still, needs to get and pay.
|
||||
|
||||
sleOfferDir = mEngine->entryCache(ltDIR_NODE, mEngine->getLedger()->getNextLedgerIndex(uTipIndex, uBookEnd));
|
||||
if (sleOfferDir)
|
||||
{
|
||||
Log(lsINFO) << "takeOffers: possible counter offer found";
|
||||
|
||||
uTipIndex = sleOfferDir->getIndex();
|
||||
uTipQuality = Ledger::getQuality(uTipIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "takeOffers: counter offer book is empty: "
|
||||
<< uTipIndex.ToString()
|
||||
<< " ... "
|
||||
<< uBookEnd.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if (!sleOfferDir // No offer directory to take.
|
||||
|| uTakeQuality < uTipQuality // No offers of sufficient quality available.
|
||||
|| (bPassive && uTakeQuality == uTipQuality))
|
||||
{
|
||||
// Done.
|
||||
Log(lsINFO) << "takeOffers: done";
|
||||
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have an offer directory to consider.
|
||||
Log(lsINFO) << "takeOffers: considering dir: " << sleOfferDir->getJson(0);
|
||||
|
||||
SLE::pointer sleBookNode;
|
||||
unsigned int uBookEntry;
|
||||
uint256 uOfferIndex;
|
||||
|
||||
mEngine->getNodes().dirFirst(uTipIndex, sleBookNode, uBookEntry, uOfferIndex);
|
||||
|
||||
SLE::pointer sleOffer = mEngine->entryCache(ltOFFER, uOfferIndex);
|
||||
|
||||
Log(lsINFO) << "takeOffers: considering offer : " << sleOffer->getJson(0);
|
||||
|
||||
const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID();
|
||||
STAmount saOfferPays = sleOffer->getFieldAmount(sfTakerGets);
|
||||
STAmount saOfferGets = sleOffer->getFieldAmount(sfTakerPays);
|
||||
|
||||
if (sleOffer->isFieldPresent(sfExpiration) && sleOffer->getFieldU32(sfExpiration) <= mEngine->getLedger()->getParentCloseTimeNC())
|
||||
{
|
||||
// Offer is expired. Expired offers are considered unfunded. Delete it.
|
||||
Log(lsINFO) << "takeOffers: encountered expired offer";
|
||||
|
||||
usOfferUnfundedFound.insert(uOfferIndex);
|
||||
}
|
||||
else if (uOfferOwnerID == uTakerAccountID)
|
||||
{
|
||||
// Would take own offer. Consider old offer expired. Delete it.
|
||||
Log(lsINFO) << "takeOffers: encountered taker's own old offer";
|
||||
|
||||
usOfferUnfundedFound.insert(uOfferIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get offer funds available.
|
||||
|
||||
Log(lsINFO) << "takeOffers: saOfferPays=" << saOfferPays.getFullText();
|
||||
|
||||
STAmount saOfferFunds = mEngine->getNodes().accountFunds(uOfferOwnerID, saOfferPays);
|
||||
STAmount saTakerFunds = mEngine->getNodes().accountFunds(uTakerAccountID, saTakerPays);
|
||||
SLE::pointer sleOfferAccount; // Owner of offer.
|
||||
|
||||
if (!saOfferFunds.isPositive())
|
||||
{
|
||||
// Offer is unfunded, possibly due to previous balance action.
|
||||
Log(lsINFO) << "takeOffers: offer unfunded: delete";
|
||||
|
||||
boost::unordered_set<uint160>::iterator account = usAccountTouched.find(uOfferOwnerID);
|
||||
if (account != usAccountTouched.end())
|
||||
{
|
||||
// Previously touched account.
|
||||
usOfferUnfundedBecame.insert(uOfferIndex); // Delete unfunded offer on success.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Never touched source account.
|
||||
usOfferUnfundedFound.insert(uOfferIndex); // Delete found unfunded offer when possible.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
STAmount saPay = saTakerPays - saTakerPaid;
|
||||
if (saTakerFunds < saPay)
|
||||
saPay = saTakerFunds;
|
||||
STAmount saSubTakerPaid;
|
||||
STAmount saSubTakerGot;
|
||||
STAmount saTakerIssuerFee;
|
||||
STAmount saOfferIssuerFee;
|
||||
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saTakerPays: " << saTakerPays.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saTakerPaid: " << saTakerPaid.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saTakerFunds: " << saTakerFunds.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saOfferFunds: " << saOfferFunds.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saPay: " << saPay.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saOfferPays: " << saOfferPays.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saOfferGets: " << saOfferGets.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saTakerPays: " << saTakerPays.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saTakerGets: " << saTakerGets.getFullText();
|
||||
|
||||
bool bOfferDelete = STAmount::applyOffer(
|
||||
mEngine->getNodes().rippleTransferRate(uTakerAccountID, uOfferOwnerID, uTakerPaysAccountID),
|
||||
mEngine->getNodes().rippleTransferRate(uOfferOwnerID, uTakerAccountID, uTakerGetsAccountID),
|
||||
saOfferFunds,
|
||||
saPay, // Driver XXX need to account for fees.
|
||||
saOfferPays,
|
||||
saOfferGets,
|
||||
saTakerPays,
|
||||
saTakerGets,
|
||||
saSubTakerPaid,
|
||||
saSubTakerGot,
|
||||
saTakerIssuerFee,
|
||||
saOfferIssuerFee);
|
||||
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saSubTakerPaid: " << saSubTakerPaid.getFullText();
|
||||
Log(lsINFO) << "takeOffers: applyOffer: saSubTakerGot: " << saSubTakerGot.getFullText();
|
||||
|
||||
// Adjust offer
|
||||
|
||||
// Offer owner will pay less. Subtract what taker just got.
|
||||
sleOffer->setFieldAmount(sfTakerGets, saOfferPays -= saSubTakerGot);
|
||||
|
||||
// Offer owner will get less. Subtract what owner just paid.
|
||||
sleOffer->setFieldAmount(sfTakerPays, saOfferGets -= saSubTakerPaid);
|
||||
|
||||
mEngine->entryModify(sleOffer);
|
||||
|
||||
if (bOfferDelete)
|
||||
{
|
||||
// Offer now fully claimed or now unfunded.
|
||||
Log(lsINFO) << "takeOffers: offer claimed: delete";
|
||||
|
||||
usOfferUnfundedBecame.insert(uOfferIndex); // Delete unfunded offer on success.
|
||||
|
||||
// Offer owner's account is no longer pristine.
|
||||
usAccountTouched.insert(uOfferOwnerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(lsINFO) << "takeOffers: offer partial claim.";
|
||||
}
|
||||
|
||||
// Offer owner pays taker.
|
||||
// saSubTakerGot.setIssuer(uTakerGetsAccountID); // XXX Move this earlier?
|
||||
assert(!!saSubTakerGot.getIssuer());
|
||||
|
||||
mEngine->getNodes().accountSend(uOfferOwnerID, uTakerAccountID, saSubTakerGot);
|
||||
mEngine->getNodes().accountSend(uOfferOwnerID, uTakerGetsAccountID, saOfferIssuerFee);
|
||||
|
||||
saTakerGot += saSubTakerGot;
|
||||
|
||||
// Taker pays offer owner.
|
||||
// saSubTakerPaid.setIssuer(uTakerPaysAccountID);
|
||||
assert(!!saSubTakerPaid.getIssuer());
|
||||
|
||||
mEngine->getNodes().accountSend(uTakerAccountID, uOfferOwnerID, saSubTakerPaid);
|
||||
mEngine->getNodes().accountSend(uTakerAccountID, uTakerPaysAccountID, saTakerIssuerFee);
|
||||
|
||||
saTakerPaid += saSubTakerPaid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On storing meta data, delete offers that were found unfunded to prevent encountering them in future.
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
BOOST_FOREACH(const uint256& uOfferIndex, usOfferUnfundedFound)
|
||||
{
|
||||
terResult = mEngine->getNodes().offerDelete(uOfferIndex);
|
||||
if (tesSUCCESS != terResult)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
// On success, delete offers that became unfunded.
|
||||
BOOST_FOREACH(const uint256& uOfferIndex, usOfferUnfundedBecame)
|
||||
{
|
||||
terResult = mEngine->getNodes().offerDelete(uOfferIndex);
|
||||
if (tesSUCCESS != terResult)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
|
||||
TER OfferCreateTransactor::doApply()
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate> " << mTxn.getJson(0);
|
||||
const uint32 txFlags = mTxn.getFlags();
|
||||
const bool bPassive = isSetBit(txFlags, tfPassive);
|
||||
STAmount saTakerPays = mTxn.getFieldAmount(sfTakerPays);
|
||||
STAmount saTakerGets = mTxn.getFieldAmount(sfTakerGets);
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays.getFullText()
|
||||
% saTakerGets.getFullText());
|
||||
|
||||
const uint160 uPaysIssuerID = saTakerPays.getIssuer();
|
||||
const uint160 uGetsIssuerID = saTakerGets.getIssuer();
|
||||
const uint32 uExpiration = mTxn.getFieldU32(sfExpiration);
|
||||
const bool bHaveExpiration = mTxn.isFieldPresent(sfExpiration);
|
||||
const uint32 uSequence = mTxn.getSequence();
|
||||
|
||||
const uint256 uLedgerIndex = Ledger::getOfferIndex(mTxnAccountID, uSequence);
|
||||
SLE::pointer sleOffer = mEngine->entryCreate(ltOFFER, uLedgerIndex);
|
||||
|
||||
Log(lsINFO) << "doOfferCreate: Creating offer node: " << uLedgerIndex.ToString() << " uSequence=" << uSequence;
|
||||
|
||||
const uint160 uPaysCurrency = saTakerPays.getCurrency();
|
||||
const uint160 uGetsCurrency = saTakerGets.getCurrency();
|
||||
const uint64 uRate = STAmount::getRate(saTakerGets, saTakerPays);
|
||||
|
||||
TER terResult = tesSUCCESS;
|
||||
uint256 uDirectory; // Delete hints.
|
||||
uint64 uOwnerNode;
|
||||
uint64 uBookNode;
|
||||
|
||||
if (bHaveExpiration && !uExpiration)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad expiration";
|
||||
|
||||
terResult = temBAD_EXPIRATION;
|
||||
}
|
||||
else if (bHaveExpiration && mEngine->getLedger()->getParentCloseTimeNC() >= uExpiration)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: Expired transaction: offer expired";
|
||||
|
||||
// XXX CHARGE FEE ONLY.
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
else if (saTakerPays.isNative() && saTakerGets.isNative())
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: XRP for XRP";
|
||||
|
||||
terResult = temBAD_OFFER;
|
||||
}
|
||||
else if (!saTakerPays.isPositive() || !saTakerGets.isPositive())
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad amount";
|
||||
|
||||
terResult = temBAD_OFFER;
|
||||
}
|
||||
else if (uPaysCurrency == uGetsCurrency && uPaysIssuerID == uGetsIssuerID)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: redundant offer";
|
||||
|
||||
terResult = temREDUNDANT;
|
||||
}
|
||||
else if (saTakerPays.isNative() != !uPaysIssuerID || saTakerGets.isNative() != !uGetsIssuerID)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: Malformed offer: bad issuer";
|
||||
|
||||
terResult = temBAD_ISSUER;
|
||||
}
|
||||
else if (!mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive())
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: delay: Offers must be at least partially funded.";
|
||||
|
||||
terResult = terUNFUNDED;
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult && !saTakerPays.isNative())
|
||||
{
|
||||
SLE::pointer sleTakerPays = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uPaysIssuerID));
|
||||
|
||||
if (!sleTakerPays)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: delay: can't receive IOUs from non-existent issuer: " << RippleAddress::createHumanAccountID(uPaysIssuerID);
|
||||
|
||||
terResult = terNO_ACCOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
STAmount saOfferPaid;
|
||||
STAmount saOfferGot;
|
||||
const uint256 uTakeBookBase = Ledger::getBookBase(uGetsCurrency, uGetsIssuerID, uPaysCurrency, uPaysIssuerID);
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: take against book: %s for %s -> %s")
|
||||
% uTakeBookBase.ToString()
|
||||
% saTakerGets.getFullText()
|
||||
% saTakerPays.getFullText());
|
||||
|
||||
// Take using the parameters of the offer.
|
||||
#if 1
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: BEFORE saTakerGets=" << saTakerGets.getFullText();
|
||||
terResult = takeOffers(
|
||||
bPassive,
|
||||
uTakeBookBase,
|
||||
mTxnAccountID,
|
||||
mTxnAccount,
|
||||
saTakerGets,
|
||||
saTakerPays,
|
||||
saOfferPaid, // How much was spent.
|
||||
saOfferGot // How much was got.
|
||||
);
|
||||
#else
|
||||
terResult = tesSUCCESS;
|
||||
#endif
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers=" << terResult;
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saOfferPaid=" << saOfferPaid.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saOfferGot=" << saOfferGot.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: AFTER saTakerGets=" << saTakerGets.getFullText();
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
saTakerPays -= saOfferGot; // Reduce payin from takers by what offer just got.
|
||||
saTakerGets -= saOfferPaid; // Reduce payout to takers by what srcAccount just paid.
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerPays=" << saTakerPays.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: saTakerGets=" << saTakerGets.getFullText();
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: mTxnAccountID=" << RippleAddress::createHumanAccountID(mTxnAccountID);
|
||||
Log(lsWARNING) << "doOfferCreate: takeOffers: FUNDS=" << mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).getFullText();
|
||||
|
||||
// Log(lsWARNING) << "doOfferCreate: takeOffers: uPaysIssuerID=" << RippleAddress::createHumanAccountID(uPaysIssuerID);
|
||||
// Log(lsWARNING) << "doOfferCreate: takeOffers: uGetsIssuerID=" << RippleAddress::createHumanAccountID(uGetsIssuerID);
|
||||
|
||||
if (tesSUCCESS == terResult
|
||||
&& saTakerPays // Still wanting something.
|
||||
&& saTakerGets // Still offering something.
|
||||
&& mEngine->getNodes().accountFunds(mTxnAccountID, saTakerGets).isPositive()) // Still funded.
|
||||
{
|
||||
// We need to place the remainder of the offer into its order book.
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: offer not fully consumed: saTakerPays=%s saTakerGets=%s")
|
||||
% saTakerPays.getFullText()
|
||||
% saTakerGets.getFullText());
|
||||
|
||||
// Add offer to owner's directory.
|
||||
terResult = mEngine->getNodes().dirAdd(uOwnerNode, Ledger::getOwnerDirIndex(mTxnAccountID), uLedgerIndex);
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
uint256 uBookBase = Ledger::getBookBase(uPaysCurrency, uPaysIssuerID, uGetsCurrency, uGetsIssuerID);
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("doOfferCreate: adding to book: %s : %s/%s -> %s/%s")
|
||||
% uBookBase.ToString()
|
||||
% saTakerPays.getHumanCurrency()
|
||||
% RippleAddress::createHumanAccountID(saTakerPays.getIssuer())
|
||||
% saTakerGets.getHumanCurrency()
|
||||
% RippleAddress::createHumanAccountID(saTakerGets.getIssuer()));
|
||||
|
||||
uDirectory = Ledger::getQualityIndex(uBookBase, uRate); // Use original rate.
|
||||
|
||||
// Add offer to order book.
|
||||
terResult = mEngine->getNodes().dirAdd(uBookNode, uDirectory, uLedgerIndex);
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
Log(lsWARNING) << "doOfferCreate: sfAccount=" << RippleAddress::createHumanAccountID(mTxnAccountID);
|
||||
Log(lsWARNING) << "doOfferCreate: uPaysIssuerID=" << RippleAddress::createHumanAccountID(uPaysIssuerID);
|
||||
Log(lsWARNING) << "doOfferCreate: uGetsIssuerID=" << RippleAddress::createHumanAccountID(uGetsIssuerID);
|
||||
Log(lsWARNING) << "doOfferCreate: saTakerPays.isNative()=" << saTakerPays.isNative();
|
||||
Log(lsWARNING) << "doOfferCreate: saTakerGets.isNative()=" << saTakerGets.isNative();
|
||||
Log(lsWARNING) << "doOfferCreate: uPaysCurrency=" << saTakerPays.getHumanCurrency();
|
||||
Log(lsWARNING) << "doOfferCreate: uGetsCurrency=" << saTakerGets.getHumanCurrency();
|
||||
|
||||
sleOffer->setFieldAccount(sfAccount, mTxnAccountID);
|
||||
sleOffer->setFieldU32(sfSequence, uSequence);
|
||||
sleOffer->setFieldH256(sfBookDirectory, uDirectory);
|
||||
sleOffer->setFieldAmount(sfTakerPays, saTakerPays);
|
||||
sleOffer->setFieldAmount(sfTakerGets, saTakerGets);
|
||||
sleOffer->setFieldU64(sfOwnerNode, uOwnerNode);
|
||||
sleOffer->setFieldU64(sfBookNode, uBookNode);
|
||||
|
||||
if (uExpiration)
|
||||
sleOffer->setFieldU32(sfExpiration, uExpiration);
|
||||
|
||||
if (bPassive)
|
||||
sleOffer->setFlag(lsfPassive);
|
||||
}
|
||||
}
|
||||
|
||||
Log(lsINFO) << "doOfferCreate: final sleOffer=" << sleOffer->getJson(0);
|
||||
|
||||
return terResult;
|
||||
}
|
||||
22
src/cpp/ripple/OfferCreateTransactor.h
Normal file
22
src/cpp/ripple/OfferCreateTransactor.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "Transactor.h"
|
||||
|
||||
|
||||
class OfferCreateTransactor : public Transactor
|
||||
{
|
||||
TER takeOffers(
|
||||
bool bPassive,
|
||||
const uint256& uBookBase,
|
||||
const uint160& uTakerAccountID,
|
||||
const SLE::pointer& sleTakerAccount,
|
||||
const STAmount& saTakerPays,
|
||||
const STAmount& saTakerGets,
|
||||
STAmount& saTakerPaid,
|
||||
STAmount& saTakerGot);
|
||||
|
||||
public:
|
||||
OfferCreateTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
|
||||
TER doApply();
|
||||
};
|
||||
|
||||
|
||||
168
src/cpp/ripple/PaymentTransactor.cpp
Normal file
168
src/cpp/ripple/PaymentTransactor.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "PaymentTransactor.h"
|
||||
#include "Config.h"
|
||||
#include "RippleCalc.h"
|
||||
|
||||
#define RIPPLE_PATHS_MAX 3
|
||||
|
||||
// TODO: only have the higher fee if the account doesn't in fact exist
|
||||
void PaymentTransactor::calculateFee()
|
||||
{
|
||||
if (mTxn.getFlags() & tfCreateAccount)
|
||||
{
|
||||
mFeeDue = theConfig.FEE_ACCOUNT_CREATE;
|
||||
}else Transactor::calculateFee();
|
||||
}
|
||||
|
||||
TER PaymentTransactor::doApply()
|
||||
{
|
||||
// Ripple if source or destination is non-native or if there are paths.
|
||||
const uint32 uTxFlags = mTxn.getFlags();
|
||||
const bool bCreate = isSetBit(uTxFlags, tfCreateAccount);
|
||||
const bool bPartialPayment = isSetBit(uTxFlags, tfPartialPayment);
|
||||
const bool bLimitQuality = isSetBit(uTxFlags, tfLimitQuality);
|
||||
const bool bNoRippleDirect = isSetBit(uTxFlags, tfNoRippleDirect);
|
||||
const bool bPaths = mTxn.isFieldPresent(sfPaths);
|
||||
const bool bMax = mTxn.isFieldPresent(sfSendMax);
|
||||
const uint160 uDstAccountID = mTxn.getFieldAccount160(sfDestination);
|
||||
const STAmount saDstAmount = mTxn.getFieldAmount(sfAmount);
|
||||
const STAmount saMaxAmount = bMax
|
||||
? mTxn.getFieldAmount(sfSendMax)
|
||||
: saDstAmount.isNative()
|
||||
? saDstAmount
|
||||
: STAmount(saDstAmount.getCurrency(), mTxnAccountID, saDstAmount.getMantissa(), saDstAmount.getExponent(), saDstAmount.isNegative());
|
||||
const uint160 uSrcCurrency = saMaxAmount.getCurrency();
|
||||
const uint160 uDstCurrency = saDstAmount.getCurrency();
|
||||
|
||||
Log(lsINFO) << boost::str(boost::format("doPayment> saMaxAmount=%s saDstAmount=%s")
|
||||
% saMaxAmount.getFullText()
|
||||
% saDstAmount.getFullText());
|
||||
|
||||
if (!uDstAccountID)
|
||||
{
|
||||
Log(lsINFO) << "doPayment: Invalid transaction: Payment destination account not specified.";
|
||||
|
||||
return temDST_NEEDED;
|
||||
}
|
||||
else if (bMax && !saMaxAmount.isPositive())
|
||||
{
|
||||
Log(lsINFO) << "doPayment: Invalid transaction: bad max amount: " << saMaxAmount.getFullText();
|
||||
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (!saDstAmount.isPositive())
|
||||
{
|
||||
Log(lsINFO) << "doPayment: Invalid transaction: bad dst amount: " << saDstAmount.getFullText();
|
||||
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
|
||||
{
|
||||
Log(lsINFO) << boost::str(boost::format("doPayment: Invalid transaction: Redundant transaction: src=%s, dst=%s, src_cur=%s, dst_cur=%s")
|
||||
% mTxnAccountID.ToString()
|
||||
% uDstAccountID.ToString()
|
||||
% uSrcCurrency.ToString()
|
||||
% uDstCurrency.ToString());
|
||||
|
||||
return temREDUNDANT;
|
||||
}
|
||||
else if (bMax
|
||||
&& ((saMaxAmount == saDstAmount && saMaxAmount.getCurrency() == saDstAmount.getCurrency())
|
||||
|| (saDstAmount.isNative() && saMaxAmount.isNative())))
|
||||
{
|
||||
Log(lsINFO) << "doPayment: Invalid transaction: bad SendMax.";
|
||||
|
||||
return temINVALID;
|
||||
}
|
||||
|
||||
SLE::pointer sleDst = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
if (!sleDst)
|
||||
{
|
||||
// Destination account does not exist.
|
||||
if (bCreate && !saDstAmount.isNative())
|
||||
{
|
||||
// This restriction could be relaxed.
|
||||
Log(lsINFO) << "doPayment: Invalid transaction: Create account may only fund XRP.";
|
||||
|
||||
return temCREATEXRP;
|
||||
}
|
||||
else if (!bCreate)
|
||||
{
|
||||
Log(lsINFO) << "doPayment: Delay transaction: Destination account does not exist.";
|
||||
|
||||
return terNO_DST;
|
||||
}
|
||||
|
||||
// Create the account.
|
||||
sleDst = mEngine->entryCreate(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
|
||||
sleDst->setFieldAccount(sfAccount, uDstAccountID);
|
||||
sleDst->setFieldU32(sfSequence, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mEngine->entryModify(sleDst);
|
||||
}
|
||||
|
||||
TER terResult;
|
||||
// XXX Should bMax be sufficient to imply ripple?
|
||||
const bool bRipple = bPaths || bMax || !saDstAmount.isNative();
|
||||
|
||||
if (bRipple)
|
||||
{
|
||||
// Ripple payment
|
||||
|
||||
STPathSet spsPaths = mTxn.getFieldPathSet(sfPaths);
|
||||
STAmount saMaxAmountAct;
|
||||
STAmount saDstAmountAct;
|
||||
|
||||
terResult = isSetBit(mParams, tapOPEN_LEDGER) && spsPaths.getPathCount() > RIPPLE_PATHS_MAX
|
||||
? telBAD_PATH_COUNT
|
||||
: RippleCalc::rippleCalc(
|
||||
mEngine->getNodes(),
|
||||
saMaxAmountAct,
|
||||
saDstAmountAct,
|
||||
saMaxAmount,
|
||||
saDstAmount,
|
||||
uDstAccountID,
|
||||
mTxnAccountID,
|
||||
spsPaths,
|
||||
bPartialPayment,
|
||||
bLimitQuality,
|
||||
bNoRippleDirect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direct XRP payment.
|
||||
|
||||
STAmount saSrcXRPBalance = mTxnAccount->getFieldAmount(sfBalance);
|
||||
|
||||
if (saSrcXRPBalance < saDstAmount)
|
||||
{
|
||||
// Transaction might succeed, if applied in a different order.
|
||||
Log(lsINFO) << "doPayment: Delay transaction: Insufficient funds.";
|
||||
|
||||
terResult = terUNFUNDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTxnAccount->setFieldAmount(sfBalance, saSrcXRPBalance - saDstAmount);
|
||||
sleDst->setFieldAmount(sfBalance, sleDst->getFieldAmount(sfBalance) + saDstAmount);
|
||||
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
if (transResultInfo(terResult, strToken, strHuman))
|
||||
{
|
||||
Log(lsINFO) << boost::str(boost::format("doPayment: %s: %s") % strToken % strHuman);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
11
src/cpp/ripple/PaymentTransactor.h
Normal file
11
src/cpp/ripple/PaymentTransactor.h
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
#include "Transactor.h"
|
||||
|
||||
class PaymentTransactor : public Transactor
|
||||
{
|
||||
void calculateFee();
|
||||
public:
|
||||
PaymentTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
|
||||
TER doApply();
|
||||
};
|
||||
@@ -18,7 +18,10 @@ const int ProofOfWork::sMaxIterations(1 << 23);
|
||||
|
||||
bool ProofOfWork::isValid() const
|
||||
{
|
||||
return ((mIterations <= sMaxIterations) && (mTarget >= sMinTarget));
|
||||
if ((mIterations <= sMaxIterations) && (mTarget >= sMinTarget))
|
||||
return true;
|
||||
cLog(lsWARNING) << "Invalid PoW: " << mIterations << ", " << mTarget;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64 ProofOfWork::getDifficulty(const uint256& target, int iterations)
|
||||
@@ -33,7 +36,7 @@ uint64 ProofOfWork::getDifficulty(const uint256& target, int iterations)
|
||||
}
|
||||
|
||||
// more iterations means more hashes per iteration but also a larger final hash
|
||||
uint64 difficulty = iterations + (iterations / 4);
|
||||
uint64 difficulty = iterations + (iterations / 8);
|
||||
|
||||
// Multiply the number of hashes needed by 256 for each leading zero byte in the difficulty
|
||||
const unsigned char *ptr = target.begin();
|
||||
@@ -70,7 +73,7 @@ uint256 ProofOfWork::solve(int maxIterations) const
|
||||
while (maxIterations > 0)
|
||||
{
|
||||
buf1[1] = nonce;
|
||||
buf1[2] = uint256();
|
||||
buf1[2].zero();
|
||||
for (int i = (mIterations - 1); i >= 0; --i)
|
||||
{
|
||||
buf1[2] = getSHA512Half(buf1);
|
||||
@@ -149,7 +152,7 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
|
||||
if (fields[4] != Serializer::getSHA512Half(v).GetHex())
|
||||
{
|
||||
cLog(lsDEBUG) << "PoW " << token << " has a bad token";
|
||||
return powBADTOKEN;
|
||||
return powCORRUPT;
|
||||
}
|
||||
|
||||
uint256 challenge, target;
|
||||
@@ -178,6 +181,7 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
// if (...) return powTOOEASY;
|
||||
if (!mSolvedChallenges.insert(powMap_vt(now, challenge)).second)
|
||||
{
|
||||
cLog(lsDEBUG) << "PoW " << token << " has been reused";
|
||||
@@ -188,6 +192,77 @@ POWResult ProofOfWorkGenerator::checkProof(const std::string& token, const uint2
|
||||
return powOK;
|
||||
}
|
||||
|
||||
void ProofOfWorkGenerator::sweep()
|
||||
{
|
||||
time_t expire = time(NULL) - mValidTime;
|
||||
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
do
|
||||
{
|
||||
powMap_t::left_map::iterator it = mSolvedChallenges.left.begin();
|
||||
if (it == mSolvedChallenges.left.end())
|
||||
return;
|
||||
if (it->first >= expire)
|
||||
return;
|
||||
mSolvedChallenges.left.erase(it);
|
||||
} while(1);
|
||||
}
|
||||
|
||||
struct PowEntry
|
||||
{
|
||||
const char *target;
|
||||
int iterations;
|
||||
};
|
||||
|
||||
PowEntry PowEntries[32] =
|
||||
{
|
||||
// FIXME: These targets are too low and iteration counts too low
|
||||
// These get too difficulty before they become sufficently RAM intensive
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 256 }, // Hashes:5242880 KB=8
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 512 }, // Hashes:5242880 KB=16
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 512 }, // Hashes:10485760 KB=16
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1024 }, // Hashes:10485760 KB=32
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1024 }, // Hashes:20971520 KB=32
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2048 }, // Hashes:20971520 KB=64
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2048 }, // Hashes:41943040 KB=64
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 4096 }, // Hashes:41943040 KB=128
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 4096 }, // Hashes:83886080 KB=128
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 8192 }, // Hashes:83886080 KB=256
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 8192 }, // Hashes:167772160 KB=256
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16384 }, // Hashes:167772160 KB=512
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 32768 }, // Hashes:335544320 MB=1
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 32768 }, // Hashes:671088640 MB=1
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 65536 }, // Hashes:671088640 MB=2
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 65536 }, // Hashes:1342177280 MB=2
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 131072 }, // Hashes:1342177280 MB=4
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 131072 }, // Hashes:2684354560 MB=4
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 262144 }, // Hashes:2684354560 MB=8
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:5368709120 MB=16
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:10737418240 MB=16
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:10737418240 MB=32
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:21474836480 MB=32
|
||||
{ "0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:21474836480 MB=64
|
||||
{ "0003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:42949672960 MB=64
|
||||
{ "00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:85899345920 MB=16
|
||||
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 524288 }, // Hashes:171798691840 MB=16
|
||||
{ "00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:171798691840 MB=32
|
||||
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 1048576 }, // Hashes:343597383680 MB=32
|
||||
{ "00007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:343597383680 MB=64
|
||||
{ "00003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 2097152 }, // Hashes:687194767360 MB=64
|
||||
};
|
||||
|
||||
void ProofOfWorkGenerator::setDifficulty(int i)
|
||||
{
|
||||
assert((i >= 0) && (i <= 31));
|
||||
time_t now = time(NULL);
|
||||
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
mPowEntry = i;
|
||||
mIterations = PowEntries[i].iterations;
|
||||
mTarget.SetHex(PowEntries[i].target);
|
||||
mLastDifficultyChange = now;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ProofOfWork_suite)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( ProofOfWork_test )
|
||||
@@ -209,6 +284,27 @@ BOOST_AUTO_TEST_CASE( ProofOfWork_test )
|
||||
cLog(lsDEBUG) << "A reused nonce error is expected";
|
||||
if (gen.checkProof(pow.getToken(), solution) != powREUSED)
|
||||
BOOST_FAIL("Reuse solution not detected");
|
||||
|
||||
#ifdef SOLVE_POWS
|
||||
for (int i = 0; i < 12; ++i)
|
||||
{
|
||||
gen.setDifficulty(i);
|
||||
ProofOfWork pow = gen.getProof();
|
||||
cLog(lsINFO) << "Level: " << i << ", Estimated difficulty: " << pow.getDifficulty();
|
||||
uint256 solution = pow.solve(131072);
|
||||
if (solution.isZero())
|
||||
cLog(lsINFO) << "Giving up";
|
||||
else
|
||||
{
|
||||
cLog(lsINFO) << "Solution found";
|
||||
if (gen.checkProof(pow.getToken(), solution) != powOK)
|
||||
{
|
||||
cLog(lsFATAL) << "Solution fails";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
enum POWResult
|
||||
{
|
||||
powOK = 0,
|
||||
powREUSED = 1,
|
||||
powBADNONCE = 2,
|
||||
powBADTOKEN = 3,
|
||||
powEXPIRED = 4,
|
||||
powCORRUPT = 5,
|
||||
powREUSED = 1, // already submitted
|
||||
powBADNONCE = 2, // you didn't solve it
|
||||
powEXPIRED = 3, // time is up
|
||||
powCORRUPT = 4,
|
||||
powTOOEASY = 5, // the difficulty increased too much while you solved it
|
||||
};
|
||||
|
||||
class ProofOfWork
|
||||
@@ -62,6 +62,7 @@ protected:
|
||||
uint256 mTarget;
|
||||
time_t mLastDifficultyChange;
|
||||
int mValidTime;
|
||||
int mPowEntry;
|
||||
|
||||
powMap_t mSolvedChallenges;
|
||||
boost::mutex mLock;
|
||||
@@ -72,6 +73,7 @@ public:
|
||||
ProofOfWork getProof();
|
||||
POWResult checkProof(const std::string& token, const uint256& solution);
|
||||
uint64 getDifficulty() { return ProofOfWork::getDifficulty(mTarget, mIterations); }
|
||||
void setDifficulty(int i);
|
||||
|
||||
void loadHigh();
|
||||
void loadLow();
|
||||
|
||||
@@ -700,6 +700,8 @@ Json::Value RPCHandler::doSubmit(const Json::Value& params)
|
||||
{
|
||||
Json::Value txJSON;
|
||||
Json::Reader reader;
|
||||
|
||||
//std::string hello=params[1u].asString();
|
||||
|
||||
if (reader.parse(params[1u].asString(), txJSON))
|
||||
{
|
||||
@@ -741,10 +743,10 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
}
|
||||
|
||||
AccountState::pointer asSrc = mNetOps->getAccountState(uint256(0), srcAddress);
|
||||
if(!asSrc) return rpcError(rpcSRC_ACT_MALFORMED);
|
||||
|
||||
if( txJSON["type"]=="Payment")
|
||||
if( txJSON["TransactionType"]=="Payment")
|
||||
{
|
||||
txJSON["TransactionType"]=0;
|
||||
|
||||
RippleAddress dstAccountID;
|
||||
|
||||
@@ -764,7 +766,7 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
else txJSON["Fee"]=(int)theConfig.FEE_ACCOUNT_CREATE;
|
||||
}
|
||||
|
||||
if(!txJSON.isMember("Paths") && (!jvRequest.isMember("build_path") || jvRequest["build_path"].asBool()))
|
||||
if(!txJSON.isMember("Paths") && jvRequest.isMember("build_path") )
|
||||
{
|
||||
if(txJSON["Amount"].isObject() || txJSON.isMember("SendMax") )
|
||||
{ // we need a ripple path
|
||||
@@ -796,9 +798,12 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
||||
|
||||
Pathfinder pf(srcAddress, dstAccountID, srcCurrencyID, dstAmount);
|
||||
pf.findPaths(5, 1, spsPaths);
|
||||
txJSON["Paths"]=spsPaths.getJson(0);
|
||||
if(txJSON.isMember("Flags")) txJSON["Flags"]=txJSON["Flags"].asUInt() | 2;
|
||||
else txJSON["Flags"]=2;
|
||||
if(!spsPaths.isEmpty())
|
||||
{
|
||||
txJSON["Paths"]=spsPaths.getJson(0);
|
||||
if(txJSON.isMember("Flags")) txJSON["Flags"]=txJSON["Flags"].asUInt() | 2;
|
||||
else txJSON["Flags"]=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
src/cpp/ripple/RegularKeySetTransactor.cpp
Normal file
51
src/cpp/ripple/RegularKeySetTransactor.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "RegularKeySetTransactor.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
SETUP_LOG();
|
||||
|
||||
// TODO:
|
||||
TER RegularKeySetTransactor::checkSig()
|
||||
{
|
||||
// Transaction's signing public key must be for the source account.
|
||||
// To prove the master private key made this transaction.
|
||||
if (mSigningPubKey.getAccountID() != mTxnAccountID)
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
cLog(lsWARNING) << "sourceAccountID: " << mSigningPubKey.humanAccountID();
|
||||
cLog(lsWARNING) << "txn accountID: " << mTxn.getSourceAccount().humanAccountID();
|
||||
|
||||
return temBAD_SET_ID;
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// TODO: this should be default fee if flag isn't set
|
||||
void RegularKeySetTransactor::calculateFee()
|
||||
{
|
||||
mFeeDue = 0;
|
||||
}
|
||||
|
||||
|
||||
// TODO: change to take a fee if there is one there
|
||||
TER RegularKeySetTransactor::doApply()
|
||||
{
|
||||
std::cerr << "doRegularKeySet>" << std::endl;
|
||||
|
||||
if (mTxnAccount->getFlags() & lsfPasswordSpent)
|
||||
{
|
||||
std::cerr << "doRegularKeySet: Delay transaction: Funds already spent." << std::endl;
|
||||
|
||||
return terFUNDS_SPENT;
|
||||
}
|
||||
|
||||
mTxnAccount->setFlag(lsfPasswordSpent);
|
||||
|
||||
uint160 uAuthKeyID=mTxn.getFieldAccount160(sfRegularKey);
|
||||
mTxnAccount->setFieldAccount(sfRegularKey, uAuthKeyID);
|
||||
|
||||
|
||||
std::cerr << "doRegularKeySet<" << std::endl;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
11
src/cpp/ripple/RegularKeySetTransactor.h
Normal file
11
src/cpp/ripple/RegularKeySetTransactor.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#include "Transactor.h"
|
||||
|
||||
class RegularKeySetTransactor : public Transactor
|
||||
{
|
||||
void calculateFee();
|
||||
public:
|
||||
RegularKeySetTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
TER checkFee();
|
||||
TER checkSig();
|
||||
TER doApply();
|
||||
};
|
||||
@@ -471,15 +471,13 @@ TER RippleCalc::calcNodeDeliverRev(
|
||||
return terResult;
|
||||
}
|
||||
|
||||
// Deliver maximum amount of funds from previous node.
|
||||
// Goal: Make progress consuming the offer.
|
||||
// For current offer, get input from deliver/limbo and output to next account or deliver for next offers.
|
||||
TER RippleCalc::calcNodeDeliverFwd(
|
||||
const unsigned int uNode, // 0 < uNode < uLast
|
||||
PathState::ref pspCur,
|
||||
const bool bMultiQuality,
|
||||
const uint160& uInAccountID, // --> Input owner's account.
|
||||
const STAmount& saInFunds, // --> Funds available for delivery and fees.
|
||||
const STAmount& saInReq, // --> Limit to deliver.
|
||||
const STAmount& saInReq, // --> Amount to deliver.
|
||||
STAmount& saInAct, // <-- Amount delivered.
|
||||
STAmount& saInFees) // <-- Fees charged.
|
||||
{
|
||||
@@ -490,7 +488,9 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
PaymentNode& pnNxt = pspCur->vpnNodes[uNode+1];
|
||||
|
||||
const uint160& uNxtAccountID = pnNxt.uAccountID;
|
||||
const uint160& uCurCurrencyID = pnCur.uCurrencyID;
|
||||
const uint160& uCurIssuerID = pnCur.uIssuerID;
|
||||
const uint160& uPrvCurrencyID = pnPrv.uCurrencyID;
|
||||
const uint160& uPrvIssuerID = pnPrv.uIssuerID;
|
||||
const STAmount& saTransferRate = pnPrv.saTransferRate;
|
||||
|
||||
@@ -498,19 +498,20 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
|
||||
uint256& uDirectTip = pnCur.uDirectTip;
|
||||
|
||||
uDirectTip = 0; // Restart book searching.
|
||||
uDirectTip = 0; // Restart book searching.
|
||||
|
||||
saInAct.zero(saInFunds);
|
||||
saInFees.zero(saInFunds);
|
||||
saInAct.zero(saInReq);
|
||||
saInFees.zero(saInReq);
|
||||
saCurDeliverAct.zero(uCurCurrencyID, uCurIssuerID);
|
||||
|
||||
while (tesSUCCESS == terResult
|
||||
&& saInAct != saInReq // Did not deliver limit.
|
||||
&& saInAct + saInFees != saInFunds) // Did not deliver all funds.
|
||||
&& saInAct + saInFees != saInReq) // Did not deliver all funds.
|
||||
{
|
||||
terResult = calcNodeAdvance(uNode, pspCur, bMultiQuality, false); // If needed, advance to next funded offer.
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
// Doesn't charge input. Input funds are in limbo.
|
||||
bool& bEntryAdvance = pnCur.bEntryAdvance;
|
||||
STAmount& saOfrRate = pnCur.saOfrRate;
|
||||
uint256& uOfferIndex = pnCur.uOfferIndex;
|
||||
@@ -521,9 +522,11 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
STAmount& saTakerPays = pnCur.saTakerPays;
|
||||
STAmount& saTakerGets = pnCur.saTakerGets;
|
||||
|
||||
const STAmount saInFeeRate = uInAccountID == uPrvIssuerID || uOfrOwnerID == uPrvIssuerID // Issuer receiving or sending.
|
||||
? saOne // No fee.
|
||||
: saTransferRate; // Transfer rate of issuer.
|
||||
const STAmount saInFeeRate = !!uPrvCurrencyID
|
||||
? uInAccountID == uPrvIssuerID || uOfrOwnerID == uPrvIssuerID // Issuer receiving or sending.
|
||||
? saOne // No fee.
|
||||
: saTransferRate // Transfer rate of issuer.
|
||||
: saOne;
|
||||
|
||||
//
|
||||
// First calculate assuming no output fees.
|
||||
@@ -532,11 +535,11 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
STAmount saOutFunded = std::max(saOfferFunds, saTakerGets); // Offer maximum out - There are no out fees.
|
||||
STAmount saInFunded = STAmount::multiply(saOutFunded, saOfrRate, saInReq); // Offer maximum in - Limited by by payout.
|
||||
STAmount saInTotal = STAmount::multiply(saInFunded, saTransferRate); // Offer maximum in with fees.
|
||||
STAmount saInSum = std::min(saInTotal, saInFunds-saInAct-saInFees); // In limited by saInFunds.
|
||||
STAmount saInSum = std::min(saInTotal, saInReq-saInAct-saInFees); // In limited by saInReq.
|
||||
STAmount saInPassAct = STAmount::divide(saInSum, saInFeeRate); // In without fees.
|
||||
STAmount saOutPassMax = STAmount::divide(saInPassAct, saOfrRate, saOutFunded); // Out.
|
||||
|
||||
STAmount saInPassFees(saInFunds.getCurrency(), saInFunds.getIssuer());
|
||||
STAmount saInPassFees(saInReq.getCurrency(), saInReq.getIssuer());
|
||||
STAmount saOutPassAct(saOfferFunds.getCurrency(), saOfferFunds.getIssuer());
|
||||
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: saOutFunded=%s saInFunded=%s saInTotal=%s saInSum=%s saInPassAct=%s saOutPassMax=%s")
|
||||
@@ -551,22 +554,23 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
{
|
||||
// ? --> OFFER --> account
|
||||
// Input fees: vary based upon the consumed offer's owner.
|
||||
// Output fees: none as the destination account is the issuer.
|
||||
|
||||
// XXX This doesn't claim input.
|
||||
// XXX Assumes input is in limbo. XXX Check.
|
||||
|
||||
// Debit offer owner.
|
||||
lesActive.accountSend(uOfrOwnerID, uCurIssuerID, saOutPassMax);
|
||||
// Output fees: none as XRP or the destination account is the issuer.
|
||||
|
||||
saOutPassAct = saOutPassMax;
|
||||
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: ? --> OFFER --> account: saOutPassAct=%s")
|
||||
% saOutPassAct);
|
||||
cLog(lsDEBUG) << boost::str(boost::format("calcNodeDeliverFwd: ? --> OFFER --> account: uOfrOwnerID=%s uNxtAccountID=%s saOutPassAct=%s")
|
||||
% RippleAddress::createHumanAccountID(uOfrOwnerID)
|
||||
% RippleAddress::createHumanAccountID(uNxtAccountID)
|
||||
% saOutPassAct.getFullText());
|
||||
|
||||
// Debit offer owner, send XRP or non-XPR to next account.
|
||||
lesActive.accountSend(uOfrOwnerID, uNxtAccountID, saOutPassAct);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ? --> OFFER --> offer
|
||||
// Offer to offer means current order book's output currency and issuer match next order book's input current and
|
||||
// issuer.
|
||||
STAmount saOutPassFees;
|
||||
|
||||
terResult = RippleCalc::calcNodeDeliverFwd(
|
||||
@@ -575,16 +579,22 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
bMultiQuality,
|
||||
uOfrOwnerID,
|
||||
saOutPassMax,
|
||||
saOutPassMax,
|
||||
saOutPassAct, // <-- Amount delivered.
|
||||
saOutPassFees); // <-- Fees charged.
|
||||
|
||||
if (tesSUCCESS != terResult)
|
||||
break;
|
||||
|
||||
// Offer maximum in limited by next payout.
|
||||
// Offer maximum in split into fees by next payout.
|
||||
saInPassAct = STAmount::multiply(saOutPassAct, saOfrRate);
|
||||
saInPassFees = STAmount::multiply(saInFunded, saInFeeRate)-saInPassAct;
|
||||
|
||||
// Do outbound debiting.
|
||||
// Send to issuer/limbo total amount (no fees to issuer).
|
||||
lesActive.accountSend(uOfrOwnerID, !!uCurCurrencyID ? uCurIssuerID : ACCOUNT_XRP, saOutPassAct);
|
||||
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: ? --> OFFER --> offer: saOutPassAct=%s")
|
||||
% saOutPassAct);
|
||||
}
|
||||
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeDeliverFwd: saTakerGets=%s saTakerPays=%s saInPassAct=%s saOutPassAct=%s")
|
||||
@@ -596,13 +606,12 @@ TER RippleCalc::calcNodeDeliverFwd(
|
||||
// Funds were spent.
|
||||
bFundsDirty = true;
|
||||
|
||||
// Credit issuer transfer fees.
|
||||
lesActive.accountSend(uInAccountID, uOfrOwnerID, saInPassFees);
|
||||
|
||||
// Credit offer owner from offer.
|
||||
lesActive.accountSend(uInAccountID, uOfrOwnerID, saInPassAct);
|
||||
// Do inbound crediting.
|
||||
// Credit offer owner from in issuer/limbo (don't take transfer fees).
|
||||
lesActive.accountSend(!!uPrvCurrencyID ? uInAccountID : ACCOUNT_XRP, uOfrOwnerID, saInPassAct);
|
||||
|
||||
// Adjust offer
|
||||
// Fees are considered paid from a seperate budget and are not named in the offer.
|
||||
sleOffer->setFieldAmount(sfTakerGets, saTakerGets - saOutPassAct);
|
||||
sleOffer->setFieldAmount(sfTakerPays, saTakerPays - saInPassAct);
|
||||
|
||||
@@ -661,7 +670,7 @@ TER RippleCalc::calcNodeOfferRev(
|
||||
}
|
||||
|
||||
// Called to drive the from the first offer node in a chain.
|
||||
// - Offer input is limbo.
|
||||
// - Offer input is in issuer/limbo.
|
||||
// - Current offers consumed.
|
||||
// - Current offer owners debited.
|
||||
// - Transfer fees credited to issuer.
|
||||
@@ -688,7 +697,6 @@ TER RippleCalc::calcNodeOfferFwd(
|
||||
bMultiQuality,
|
||||
pnPrv.uAccountID,
|
||||
pnPrv.saFwdDeliver,
|
||||
pnPrv.saFwdDeliver,
|
||||
saInAct,
|
||||
saInFees);
|
||||
|
||||
@@ -843,6 +851,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uNode, PathState::ref pspC
|
||||
|
||||
const uint160& uCurrencyID = pnCur.uCurrencyID;
|
||||
|
||||
// XXX Don't look up quality for XRP
|
||||
const uint32 uQualityIn = uNode ? lesActive.rippleQualityIn(uCurAccountID, uPrvAccountID, uCurrencyID) : QUALITY_ONE;
|
||||
const uint32 uQualityOut = uNode != uLast ? lesActive.rippleQualityOut(uCurAccountID, uNxtAccountID, uCurrencyID) : QUALITY_ONE;
|
||||
|
||||
@@ -908,15 +917,16 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uNode, PathState::ref pspC
|
||||
|| !saNxtOwed.isNegative() // saNxtOwed >= 0: Sender not holding next IOUs, saNxtOwed < 0: Sender holding next IOUs.
|
||||
|| -saNxtOwed == saCurRedeemReq); // If issue req, then redeem req must consume all owed.
|
||||
|
||||
if (bPrvAccount && bNxtAccount)
|
||||
if (!uNode)
|
||||
{
|
||||
if (!uNode)
|
||||
{
|
||||
// ^ --> ACCOUNT --> account|offer
|
||||
// Nothing to do, there is no previous to adjust.
|
||||
nothing();
|
||||
}
|
||||
else if (uNode == uLast)
|
||||
// ^ --> ACCOUNT --> account|offer
|
||||
// Nothing to do, there is no previous to adjust.
|
||||
|
||||
nothing();
|
||||
}
|
||||
else if (bPrvAccount && bNxtAccount)
|
||||
{
|
||||
if (uNode == uLast)
|
||||
{
|
||||
// account --> ACCOUNT --> $
|
||||
// Overall deliverable.
|
||||
@@ -1157,7 +1167,7 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uNode, PathState::ref pspC
|
||||
}
|
||||
|
||||
// The reverse pass has been narrowing by credit available and inflating by fees as it worked backwards.
|
||||
// Now, push through the actual amount to each node and adjust balances.
|
||||
// Now, for the current account node, take the actual amount from previous and adjust forward balances.
|
||||
//
|
||||
// Perform balance adjustments between previous and current node.
|
||||
// - The previous node: specifies what to push through to current.
|
||||
@@ -1165,6 +1175,8 @@ TER RippleCalc::calcNodeAccountRev(const unsigned int uNode, PathState::ref pspC
|
||||
// Then, compute current node's output for next node.
|
||||
// - Current node: specify what to push through to next.
|
||||
// - Output to next node is computed as input minus quality or transfer fee.
|
||||
// - If next node is an offer and output is non-XRP then we are the issuer and do not need to push funds.
|
||||
// - If next node is an offer and output is XRP then we need to deliver funds to limbo.
|
||||
TER RippleCalc::calcNodeAccountFwd(
|
||||
const unsigned int uNode, // 0 <= uNode <= uLast
|
||||
PathState::ref pspCur,
|
||||
@@ -1186,6 +1198,8 @@ TER RippleCalc::calcNodeAccountFwd(
|
||||
const uint160& uPrvAccountID = bPrvAccount ? pnPrv.uAccountID : uCurAccountID;
|
||||
const uint160& uNxtAccountID = bNxtAccount ? pnNxt.uAccountID : uCurAccountID; // Offers are always issue.
|
||||
|
||||
// const uint160& uCurIssuerID = pnCur.uIssuerID;
|
||||
|
||||
const uint160& uCurrencyID = pnCur.uCurrencyID;
|
||||
|
||||
uint32 uQualityIn = uNode ? lesActive.rippleQualityIn(uCurAccountID, uPrvAccountID, uCurrencyID) : QUALITY_ONE;
|
||||
@@ -1216,6 +1230,9 @@ TER RippleCalc::calcNodeAccountFwd(
|
||||
const STAmount& saCurDeliverReq = pnCur.saRevDeliver;
|
||||
STAmount& saCurDeliverAct = pnCur.saFwdDeliver;
|
||||
|
||||
// For !uNode
|
||||
STAmount& saCurSendMaxPass = pspCur->saInPass; // Report how much pass sends.
|
||||
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd> uNode=%d/%d saPrvRedeemReq=%s saPrvIssueReq=%s saPrvDeliverReq=%s saCurRedeemReq=%s saCurIssueReq=%s saCurDeliverReq=%s")
|
||||
% uNode
|
||||
% uLast
|
||||
@@ -1238,37 +1255,31 @@ TER RippleCalc::calcNodeAccountFwd(
|
||||
|
||||
// First node, calculate amount to ripple based on what is available.
|
||||
|
||||
// Limit by sendmax.
|
||||
const STAmount saCurSendMaxReq = pspCur->saInReq.isNegative()
|
||||
? pspCur->saInReq // Negative for no limit, doing a calculation.
|
||||
: pspCur->saInReq-pspCur->saInAct; // request - done.
|
||||
STAmount& saCurSendMaxPass = pspCur->saInPass; // Report how much pass sends.
|
||||
saCurRedeemAct = saCurRedeemReq;
|
||||
|
||||
if (!pspCur->saInReq.isNegative())
|
||||
{
|
||||
// Limit by send max.
|
||||
saCurRedeemAct = std::min(saCurRedeemAct, pspCur->saInReq-pspCur->saInAct);
|
||||
}
|
||||
|
||||
saCurRedeemAct = saCurRedeemReq
|
||||
// Redeem requested.
|
||||
? saCurRedeemReq.isNegative()
|
||||
? saCurRedeemReq
|
||||
: std::min(saCurRedeemReq, saCurSendMaxReq)
|
||||
// No redeeming.
|
||||
: saCurRedeemReq;
|
||||
saCurSendMaxPass = saCurRedeemAct;
|
||||
|
||||
saCurIssueAct = (saCurIssueReq // Issue wanted.
|
||||
&& (saCurSendMaxReq.isNegative() // No limit.
|
||||
|| saCurSendMaxPass != saCurSendMaxReq)) // Not yet satisfied.
|
||||
// Issue requested and pass does not meet max.
|
||||
? saCurSendMaxReq.isNegative()
|
||||
? saCurIssueReq
|
||||
: std::min(saCurSendMaxReq-saCurRedeemAct, saCurIssueReq)
|
||||
// No issuing.
|
||||
saCurIssueAct = saCurRedeemAct == saCurRedeemReq // Fully redeemed.
|
||||
? saCurIssueReq
|
||||
: STAmount(saCurIssueReq);
|
||||
|
||||
if (!!saCurIssueAct && !pspCur->saInReq.isNegative())
|
||||
{
|
||||
// Limit by send max.
|
||||
saCurIssueAct = std::min(saCurIssueAct, pspCur->saInReq-pspCur->saInAct-saCurRedeemAct);
|
||||
}
|
||||
|
||||
saCurSendMaxPass += saCurIssueAct;
|
||||
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: ^ --> ACCOUNT --> account : saInReq=%s saInAct=%s saCurSendMaxReq=%s saCurRedeemAct=%s saCurIssueReq=%s saCurIssueAct=%s saCurSendMaxPass=%s")
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: ^ --> ACCOUNT --> account : saInReq=%s saInAct=%s saCurRedeemAct=%s saCurIssueReq=%s saCurIssueAct=%s saCurSendMaxPass=%s")
|
||||
% pspCur->saInReq.getFullText()
|
||||
% pspCur->saInAct.getFullText()
|
||||
% saCurSendMaxReq.getFullText()
|
||||
% saCurRedeemAct.getFullText()
|
||||
% saCurIssueReq.getFullText()
|
||||
% saCurIssueAct.getFullText()
|
||||
@@ -1343,31 +1354,72 @@ TER RippleCalc::calcNodeAccountFwd(
|
||||
}
|
||||
else if (bPrvAccount && !bNxtAccount)
|
||||
{
|
||||
// account --> ACCOUNT --> offer
|
||||
cLog(lsINFO) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> offer"));
|
||||
|
||||
saCurDeliverAct.zero(saCurDeliverReq);
|
||||
|
||||
// redeem -> issue.
|
||||
// wants to redeem and current would and can issue.
|
||||
// If redeeming cur to next is done, this implies can issue.
|
||||
if (saPrvRedeemReq) // Previous wants to redeem.
|
||||
if (uNode)
|
||||
{
|
||||
// Rate : 1.0 : transfer_rate
|
||||
calcNodeRipple(QUALITY_ONE, lesActive.rippleTransferRate(uCurAccountID), saPrvRedeemReq, saCurDeliverReq, saPrvRedeemAct, saCurDeliverAct, uRateMax);
|
||||
}
|
||||
// Non-XRP, current node is the issuer.
|
||||
cLog(lsDEBUG) << boost::str(boost::format("calcNodeAccountFwd: account --> ACCOUNT --> offer"));
|
||||
|
||||
// issue -> issue
|
||||
if (saPrvRedeemReq == saPrvRedeemAct // Previous done redeeming: Previous has no IOUs.
|
||||
&& saPrvIssueReq) // Previous wants to issue. To next must be ok.
|
||||
saCurDeliverAct.zero(saCurDeliverReq);
|
||||
|
||||
// redeem -> issue/deliver.
|
||||
// Previous wants to redeem.
|
||||
// Current is issuing to an offer so leave funds in account as "limbo".
|
||||
if (saPrvRedeemReq) // Previous wants to redeem.
|
||||
{
|
||||
// Rate : 1.0 : transfer_rate
|
||||
// XXX Is having the transfer rate here correct?
|
||||
calcNodeRipple(QUALITY_ONE, lesActive.rippleTransferRate(uCurAccountID), saPrvRedeemReq, saCurDeliverReq, saPrvRedeemAct, saCurDeliverAct, uRateMax);
|
||||
}
|
||||
|
||||
// issue -> issue/deliver
|
||||
if (saPrvRedeemReq == saPrvRedeemAct // Previous done redeeming: Previous has no IOUs.
|
||||
&& saPrvIssueReq) // Previous wants to issue. To next must be ok.
|
||||
{
|
||||
// Rate: quality in : 1.0
|
||||
calcNodeRipple(uQualityIn, QUALITY_ONE, saPrvIssueReq, saCurDeliverReq, saPrvIssueAct, saCurDeliverAct, uRateMax);
|
||||
}
|
||||
|
||||
// Adjust prv --> cur balance : take all inbound
|
||||
lesActive.rippleCredit(uPrvAccountID, uCurAccountID, saPrvRedeemReq + saPrvIssueReq, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rate: quality in : 1.0
|
||||
calcNodeRipple(uQualityIn, QUALITY_ONE, saPrvIssueReq, saCurDeliverReq, saPrvIssueAct, saCurDeliverAct, uRateMax);
|
||||
}
|
||||
// Delivering amount requested from downstream.
|
||||
saCurDeliverAct = saCurDeliverReq;
|
||||
|
||||
// Adjust prv --> cur balance : take all inbound
|
||||
// XXX Currency must be in amount.
|
||||
lesActive.rippleCredit(uPrvAccountID, uCurAccountID, saPrvRedeemReq + saPrvIssueReq, false);
|
||||
// If limited, then limit by send max and available.
|
||||
if (!pspCur->saInReq.isNegative())
|
||||
{
|
||||
// Limit by send max.
|
||||
saCurDeliverAct = std::min(saCurDeliverAct, pspCur->saInReq-pspCur->saInAct);
|
||||
|
||||
// Limit XRP by available. No limit for non-XRP as issuer.
|
||||
if (!uCurAccountID)
|
||||
saCurDeliverAct = std::min(saCurDeliverAct, lesActive.accountHolds(uCurAccountID, CURRENCY_XRP, ACCOUNT_XRP));
|
||||
|
||||
}
|
||||
saCurSendMaxPass = saCurDeliverAct; // Record amount sent for pass.
|
||||
|
||||
if (!!uCurrencyID)
|
||||
{
|
||||
// Non-XRP, current node is the issuer.
|
||||
// We could be delivering to multiple accounts, so we don't know which ripple balance will be adjusted. Assume
|
||||
// just issuing.
|
||||
|
||||
cLog(lsDEBUG) << boost::str(boost::format("calcNodeAccountFwd: ^ --> ACCOUNT -- !XRP --> offer"));
|
||||
|
||||
// As the issuer, would only issue.
|
||||
// Don't need to actually deliver. As from delivering leave in the issuer as limbo.
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
cLog(lsDEBUG) << boost::str(boost::format("calcNodeAccountFwd: ^ --> ACCOUNT -- XRP --> offer"));
|
||||
|
||||
// Deliver XRP to limbo.
|
||||
lesActive.accountSend(uCurAccountID, ACCOUNT_XRP, saCurDeliverAct);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!bPrvAccount && bNxtAccount)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __RIPPLE_CALC__
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include "LedgerEntrySet.h"
|
||||
|
||||
@@ -163,7 +164,6 @@ public:
|
||||
PathState::ref pspCur,
|
||||
const bool bMultiQuality,
|
||||
const uint160& uInAccountID,
|
||||
const STAmount& saInFunds,
|
||||
const STAmount& saInReq,
|
||||
STAmount& saInAct,
|
||||
STAmount& saInFees);
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
FIELD(PreviousTxnID, HASH256, 5)
|
||||
FIELD(LedgerIndex, HASH256, 6)
|
||||
FIELD(WalletLocator, HASH256, 7)
|
||||
FIELD(RootIndex, HASH256, 8)
|
||||
|
||||
// 256-bit (uncommon)
|
||||
FIELD(BookDirectory, HASH256, 16)
|
||||
@@ -116,7 +117,7 @@
|
||||
FIELD(Destination, ACCOUNT, 3)
|
||||
FIELD(Issuer, ACCOUNT, 4)
|
||||
FIELD(Target, ACCOUNT, 7)
|
||||
FIELD(AuthorizedKey, ACCOUNT, 8)
|
||||
FIELD(RegularKey, ACCOUNT, 8)
|
||||
|
||||
// path set
|
||||
FIELD(Paths, PATHSET, 1)
|
||||
|
||||
@@ -138,7 +138,7 @@ void STObject::set(const std::vector<SOElement::ptr>& type)
|
||||
BOOST_FOREACH(const SOElement::ptr& elem, type)
|
||||
{
|
||||
mType.push_back(elem);
|
||||
if (elem->flags == SOE_OPTIONAL)
|
||||
if (elem->flags != SOE_REQUIRED)
|
||||
giveObject(makeNonPresentObject(elem->e_field));
|
||||
else
|
||||
giveObject(makeDefaultObject(elem->e_field));
|
||||
@@ -159,12 +159,18 @@ bool STObject::setType(const std::vector<SOElement::ptr> &type)
|
||||
{
|
||||
match = true;
|
||||
newData.push_back(mData.release(it).release());
|
||||
if ((elem->flags == SOE_DEFAULT) && it->isDefault())
|
||||
{
|
||||
cLog(lsWARNING) << "setType( " << getFName().getName() << ") invalid default "
|
||||
<< elem->e_field.fieldName;
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
if (elem->flags != SOE_OPTIONAL)
|
||||
if (elem->flags == SOE_REQUIRED)
|
||||
{
|
||||
cLog(lsWARNING) << "setType( " << getFName().getName() << ") invalid missing "
|
||||
<< elem->e_field.fieldName;
|
||||
|
||||
@@ -688,7 +688,7 @@ public:
|
||||
void addPath(const STPath& e) { value.push_back(e); }
|
||||
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
virtual bool isDefault() const { return value.empty(); }
|
||||
virtual bool isDefault() const { return value.empty(); }
|
||||
|
||||
void printDebug();
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#define __TRANSACTION__
|
||||
|
||||
//
|
||||
// Notes: this code contains legacy constructored sharedXYZ and setXYZ. The intent is for these functions to go away. Transactions
|
||||
// should now be constructed in JSON with. Use STObject::parseJson to obtain a binary version.
|
||||
// Transactions should be constructed in JSON with. Use STObject::parseJson to obtain a binary version.
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,10 @@
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
#include "TransactionEngine.h"
|
||||
#include "Transactor.h"
|
||||
|
||||
#include "../json/writer.h"
|
||||
|
||||
@@ -88,401 +90,74 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
|
||||
}
|
||||
#endif
|
||||
|
||||
TER terResult = tesSUCCESS;
|
||||
uint256 txID = txn.getTransactionID();
|
||||
if (!txID)
|
||||
Transactor::pointer transactor=Transactor::makeTransactor(txn,params,this);
|
||||
if(transactor)
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: invalid transaction id";
|
||||
|
||||
terResult = temINVALID;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify transaction is signed properly.
|
||||
//
|
||||
|
||||
// Extract signing key
|
||||
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
|
||||
// without going to disk. Each transaction also notes a source account id. This is used to verify that the signing key is
|
||||
// associated with the account.
|
||||
// XXX This could be a lot cleaner to prevent unnecessary copying.
|
||||
RippleAddress naSigningPubKey;
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
naSigningPubKey = RippleAddress::createAccountPublic(txn.getSigningPubKey());
|
||||
|
||||
// Consistency: really signed.
|
||||
if ((tesSUCCESS == terResult) && !isSetBit(params, tapNO_CHECK_SIGN) && !txn.checkSign(naSigningPubKey))
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: Invalid transaction: bad signature";
|
||||
|
||||
terResult = temINVALID;
|
||||
}
|
||||
|
||||
STAmount saCost = theConfig.FEE_DEFAULT;
|
||||
|
||||
// Customize behavior based on transaction type.
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
switch (txn.getTxnType())
|
||||
uint256 txID = txn.getTransactionID();
|
||||
if (!txID)
|
||||
{
|
||||
case ttCLAIM:
|
||||
case ttREGULAR_KEY_SET:
|
||||
saCost = 0;
|
||||
break;
|
||||
cLog(lsWARNING) << "applyTransaction: invalid transaction id";
|
||||
|
||||
case ttPAYMENT:
|
||||
if (txn.getFlags() & tfCreateAccount)
|
||||
{
|
||||
saCost = theConfig.FEE_ACCOUNT_CREATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ttNICKNAME_SET:
|
||||
{
|
||||
SLE::pointer sleNickname = entryCache(ltNICKNAME, txn.getFieldH256(sfNickname));
|
||||
|
||||
if (!sleNickname)
|
||||
saCost = theConfig.FEE_NICKNAME_CREATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ttACCOUNT_SET:
|
||||
case ttTRUST_SET:
|
||||
case ttOFFER_CREATE:
|
||||
case ttOFFER_CANCEL:
|
||||
case ttPASSWORD_FUND:
|
||||
case ttWALLET_ADD:
|
||||
nothing();
|
||||
break;
|
||||
|
||||
case ttINVALID:
|
||||
cLog(lsWARNING) << "applyTransaction: Invalid transaction: ttINVALID transaction type";
|
||||
terResult = temINVALID;
|
||||
break;
|
||||
|
||||
default:
|
||||
cLog(lsWARNING) << "applyTransaction: Invalid transaction: unknown transaction type";
|
||||
terResult = temUNKNOWN;
|
||||
break;
|
||||
return temINVALID;
|
||||
}
|
||||
}
|
||||
|
||||
STAmount saPaid = txn.getTransactionFee();
|
||||
TER terResult= transactor->apply();
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
if (saCost)
|
||||
transResultInfo(terResult, strToken, strHuman);
|
||||
|
||||
cLog(lsINFO) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman;
|
||||
|
||||
if (isTepPartial(terResult) && isSetBit(params, tapRETRY))
|
||||
{
|
||||
// Only check fee is sufficient when the ledger is open.
|
||||
if (isSetBit(params, tapOPEN_LEDGER) && saPaid < saCost)
|
||||
// Partial result and allowed to retry, reclassify as a retry.
|
||||
terResult = terRETRY;
|
||||
}
|
||||
|
||||
if ((tesSUCCESS == terResult) || isTepPartial(terResult))
|
||||
{
|
||||
// Transaction succeeded fully or (retries are not allowed and the transaction succeeded partially).
|
||||
Serializer m;
|
||||
mNodes.calcRawMeta(m, terResult);
|
||||
|
||||
txnWrite();
|
||||
|
||||
Serializer s;
|
||||
txn.add(s);
|
||||
|
||||
if (isSetBit(params, tapOPEN_LEDGER))
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: insufficient fee";
|
||||
|
||||
terResult = telINSUF_FEE_P;
|
||||
if (!mLedger->addTransaction(txID, s))
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (saPaid)
|
||||
{
|
||||
// Transaction is malformed.
|
||||
cLog(lsWARNING) << "applyTransaction: fee not allowed";
|
||||
|
||||
terResult = temINSUF_FEE_P;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get source account ID.
|
||||
mTxnAccountID = txn.getSourceAccount().getAccountID();
|
||||
if (tesSUCCESS == terResult && !mTxnAccountID)
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: bad source id";
|
||||
|
||||
terResult = temINVALID;
|
||||
}
|
||||
|
||||
if (tesSUCCESS != terResult)
|
||||
return terResult;
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
|
||||
|
||||
mTxnAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(mTxnAccountID));
|
||||
|
||||
// Find source account
|
||||
// If are only forwarding, due to resource limitations, we might verifying only some transactions, this would be probablistic.
|
||||
|
||||
STAmount saSrcBalance;
|
||||
uint32 t_seq = txn.getSequence();
|
||||
bool bHaveAuthKey = false;
|
||||
|
||||
if (!mTxnAccount)
|
||||
{
|
||||
cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") %
|
||||
txn.getSourceAccount().humanAccountID());
|
||||
|
||||
terResult = terNO_ACCOUNT;
|
||||
}
|
||||
else
|
||||
{
|
||||
saSrcBalance = mTxnAccount->getFieldAmount(sfBalance);
|
||||
bHaveAuthKey = mTxnAccount->isFieldPresent(sfAuthorizedKey);
|
||||
}
|
||||
|
||||
// Check if account claimed.
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
switch (txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
if (bHaveAuthKey)
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: Account already claimed.";
|
||||
|
||||
terResult = tefCLAIMED;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
nothing();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Consistency: Check signature
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
switch (txn.getTxnType())
|
||||
{
|
||||
case ttCLAIM:
|
||||
// Transaction's signing public key must be for the source account.
|
||||
// To prove the master private key made this transaction.
|
||||
if (naSigningPubKey.getAccountID() != mTxnAccountID)
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
cLog(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID();
|
||||
cLog(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID();
|
||||
|
||||
terResult = tefBAD_CLAIM_ID;
|
||||
}
|
||||
break;
|
||||
|
||||
case ttREGULAR_KEY_SET:
|
||||
// Transaction's signing public key must be for the source account.
|
||||
// To prove the master private key made this transaction.
|
||||
if (naSigningPubKey.getAccountID() != mTxnAccountID)
|
||||
{
|
||||
// Signing Pub Key must be for Source Account ID.
|
||||
cLog(lsWARNING) << "sourceAccountID: " << naSigningPubKey.humanAccountID();
|
||||
cLog(lsWARNING) << "txn accountID: " << txn.getSourceAccount().humanAccountID();
|
||||
|
||||
terResult = temBAD_SET_ID;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Verify the transaction's signing public key is the key authorized for signing.
|
||||
if (bHaveAuthKey && naSigningPubKey.getAccountID() == mTxnAccount->getFieldAccount(sfAuthorizedKey).getAccountID())
|
||||
{
|
||||
// Authorized to continue.
|
||||
nothing();
|
||||
}
|
||||
else if (naSigningPubKey.getAccountID() == mTxnAccountID)
|
||||
{
|
||||
// Authorized to continue.
|
||||
nothing();
|
||||
}
|
||||
else if (bHaveAuthKey)
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: Delay: Not authorized to use account.";
|
||||
|
||||
terResult = tefBAD_AUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: Invalid: Not authorized to use account.";
|
||||
|
||||
terResult = temBAD_AUTH_MASTER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Deduct the fee, so it's not available during the transaction.
|
||||
// Will only write the account back, if the transaction succeeds.
|
||||
if (tesSUCCESS != terResult || !saCost)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
else if (saSrcBalance < saPaid)
|
||||
{
|
||||
cLog(lsINFO)
|
||||
<< boost::str(boost::format("applyTransaction: Delay: insufficient balance: balance=%s paid=%s")
|
||||
% saSrcBalance.getText()
|
||||
% saPaid.getText());
|
||||
|
||||
terResult = terINSUF_FEE_B;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTxnAccount->setFieldAmount(sfBalance, saSrcBalance - saPaid);
|
||||
}
|
||||
|
||||
// Validate sequence
|
||||
if (tesSUCCESS != terResult)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
else if (saCost)
|
||||
{
|
||||
uint32 a_seq = mTxnAccount->getFieldU32(sfSequence);
|
||||
|
||||
cLog(lsTRACE) << "Aseq=" << a_seq << ", Tseq=" << t_seq;
|
||||
|
||||
if (t_seq != a_seq)
|
||||
{
|
||||
if (a_seq < t_seq)
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: future sequence number";
|
||||
|
||||
terResult = terPRE_SEQ;
|
||||
}
|
||||
else if (mLedger->hasTransaction(txID))
|
||||
terResult = tefALREADY;
|
||||
else
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: past sequence number";
|
||||
if (!mLedger->addTransaction(txID, s, m))
|
||||
assert(false);
|
||||
|
||||
terResult = tefPAST_SEQ;
|
||||
STAmount saPaid = txn.getTransactionFee();
|
||||
// Charge whatever fee they specified.
|
||||
mLedger->destroyCoins(saPaid.getNValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
mTxnAccount.reset();
|
||||
mNodes.clear();
|
||||
|
||||
if (!isSetBit(params, tapOPEN_LEDGER)
|
||||
&& (isTemMalformed(terResult) || isTefFailure(terResult)))
|
||||
{
|
||||
mTxnAccount->setFieldU32(sfSequence, t_seq + 1);
|
||||
// XXX Malformed or failed transaction in closed ledger must bow out.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
return terResult;
|
||||
}else
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: Zero cost transaction";
|
||||
|
||||
if (t_seq)
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: bad sequence for pre-paid transaction";
|
||||
|
||||
terResult = tefPAST_SEQ;
|
||||
}
|
||||
cLog(lsWARNING) << "applyTransaction: Invalid transaction: unknown transaction type";
|
||||
return temUNKNOWN;
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
entryModify(mTxnAccount);
|
||||
|
||||
switch (txn.getTxnType())
|
||||
{
|
||||
case ttACCOUNT_SET:
|
||||
terResult = doAccountSet(txn);
|
||||
break;
|
||||
|
||||
case ttCLAIM:
|
||||
terResult = doClaim(txn);
|
||||
break;
|
||||
|
||||
case ttTRUST_SET:
|
||||
terResult = doTrustSet(txn);
|
||||
break;
|
||||
|
||||
case ttINVALID:
|
||||
cLog(lsINFO) << "applyTransaction: invalid type";
|
||||
terResult = temINVALID;
|
||||
break;
|
||||
|
||||
//case ttINVOICE:
|
||||
// terResult = doInvoice(txn);
|
||||
// break;
|
||||
|
||||
case ttOFFER_CREATE:
|
||||
terResult = doOfferCreate(txn);
|
||||
break;
|
||||
|
||||
case ttOFFER_CANCEL:
|
||||
terResult = doOfferCancel(txn);
|
||||
break;
|
||||
|
||||
case ttREGULAR_KEY_SET:
|
||||
terResult = doRegularKeySet(txn);
|
||||
break;
|
||||
|
||||
case ttPAYMENT:
|
||||
terResult = doPayment(txn, params);
|
||||
break;
|
||||
|
||||
case ttWALLET_ADD:
|
||||
terResult = doWalletAdd(txn);
|
||||
break;
|
||||
|
||||
case ttCONTRACT:
|
||||
terResult = doContractAdd(txn);
|
||||
break;
|
||||
case ttCONTRACT_REMOVE:
|
||||
terResult = doContractRemove(txn);
|
||||
break;
|
||||
|
||||
default:
|
||||
terResult = temUNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string strToken;
|
||||
std::string strHuman;
|
||||
|
||||
transResultInfo(terResult, strToken, strHuman);
|
||||
|
||||
cLog(lsINFO) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman;
|
||||
|
||||
if (isTepPartial(terResult) && isSetBit(params, tapRETRY))
|
||||
{
|
||||
// Partial result and allowed to retry, reclassify as a retry.
|
||||
terResult = terRETRY;
|
||||
}
|
||||
|
||||
if ((tesSUCCESS == terResult) || isTepPartial(terResult))
|
||||
{
|
||||
// Transaction succeeded fully or (retries are not allowed and the transaction succeeded partially).
|
||||
Serializer m;
|
||||
mNodes.calcRawMeta(m, terResult);
|
||||
|
||||
txnWrite();
|
||||
|
||||
Serializer s;
|
||||
txn.add(s);
|
||||
|
||||
if (isSetBit(params, tapOPEN_LEDGER))
|
||||
{
|
||||
if (!mLedger->addTransaction(txID, s))
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mLedger->addTransaction(txID, s, m))
|
||||
assert(false);
|
||||
|
||||
// Charge whatever fee they specified.
|
||||
mLedger->destroyCoins(saPaid.getNValue());
|
||||
}
|
||||
}
|
||||
|
||||
mTxnAccount.reset();
|
||||
mNodes.clear();
|
||||
|
||||
if (!isSetBit(params, tapOPEN_LEDGER)
|
||||
&& (isTemMalformed(terResult) || isTefFailure(terResult)))
|
||||
{
|
||||
// XXX Malformed or failed transaction in closed ledger must bow out.
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include "TransactionErr.h"
|
||||
#include "InstanceCounter.h"
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
DEFINE_INSTANCE(TransactionEngine);
|
||||
|
||||
// A TransactionEngine applies serialized transactions to a ledger
|
||||
@@ -38,6 +42,7 @@ private:
|
||||
LedgerEntrySet mNodes;
|
||||
|
||||
TER setAuthorized(const SerializedTransaction& txn, bool bMustSetGenerator);
|
||||
TER checkSig(const SerializedTransaction& txn);
|
||||
|
||||
TER takeOffers(
|
||||
bool bPassive,
|
||||
@@ -55,31 +60,26 @@ protected:
|
||||
uint160 mTxnAccountID;
|
||||
SLE::pointer mTxnAccount;
|
||||
|
||||
|
||||
|
||||
void txnWrite();
|
||||
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<TransactionEngine> pointer;
|
||||
|
||||
TransactionEngine() { ; }
|
||||
TransactionEngine(Ledger::ref ledger) : mLedger(ledger) { assert(mLedger); }
|
||||
|
||||
LedgerEntrySet& getNodes() { return mNodes; }
|
||||
Ledger::pointer getLedger() { return mLedger; }
|
||||
void setLedger(Ledger::ref ledger) { assert(ledger); mLedger = ledger; }
|
||||
|
||||
SLE::pointer entryCreate(LedgerEntryType type, const uint256& index) { return mNodes.entryCreate(type, index); }
|
||||
SLE::pointer entryCache(LedgerEntryType type, const uint256& index) { return mNodes.entryCache(type, index); }
|
||||
void entryDelete(SLE::ref sleEntry) { mNodes.entryDelete(sleEntry); }
|
||||
void entryModify(SLE::ref sleEntry) { mNodes.entryModify(sleEntry); }
|
||||
|
||||
void txnWrite();
|
||||
|
||||
TER doAccountSet(const SerializedTransaction& txn);
|
||||
TER doClaim(const SerializedTransaction& txn);
|
||||
TER doTrustSet(const SerializedTransaction& txn);
|
||||
TER doOfferCreate(const SerializedTransaction& txn);
|
||||
TER doOfferCancel(const SerializedTransaction& txn);
|
||||
TER doRegularKeySet(const SerializedTransaction& txn);
|
||||
TER doPayment(const SerializedTransaction& txn, const TransactionEngineParams params);
|
||||
TER doWalletAdd(const SerializedTransaction& txn);
|
||||
TER doContractAdd(const SerializedTransaction& txn);
|
||||
TER doContractRemove(const SerializedTransaction& txn);
|
||||
|
||||
public:
|
||||
TransactionEngine() { ; }
|
||||
TransactionEngine(Ledger::ref ledger) : mLedger(ledger) { assert(mLedger); }
|
||||
|
||||
Ledger::pointer getLedger() { return mLedger; }
|
||||
void setLedger(Ledger::ref ledger) { assert(ledger); mLedger = ledger; }
|
||||
|
||||
TER applyTransaction(const SerializedTransaction&, TransactionEngineParams);
|
||||
};
|
||||
|
||||
|
||||
@@ -45,14 +45,14 @@ static bool TFInit()
|
||||
;
|
||||
|
||||
DECLARE_TF(SetRegularKey, ttREGULAR_KEY_SET)
|
||||
<< SOElement(sfAuthorizedKey, SOE_REQUIRED)
|
||||
<< SOElement(sfRegularKey, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
DECLARE_TF(Payment, ttPAYMENT)
|
||||
<< SOElement(sfDestination, SOE_REQUIRED)
|
||||
<< SOElement(sfAmount, SOE_REQUIRED)
|
||||
<< SOElement(sfSendMax, SOE_OPTIONAL)
|
||||
<< SOElement(sfPaths, SOE_OPTIONAL)
|
||||
<< SOElement(sfPaths, SOE_DEFAULT)
|
||||
<< SOElement(sfInvoiceID, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
|
||||
220
src/cpp/ripple/Transactor.cpp
Normal file
220
src/cpp/ripple/Transactor.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
#include "Transactor.h"
|
||||
#include "Log.h"
|
||||
#include "Config.h"
|
||||
#include "PaymentTransactor.h"
|
||||
#include "RegularKeySetTransactor.h"
|
||||
#include "AccountSetTransactor.h"
|
||||
#include "WalletAddTransactor.h"
|
||||
#include "OfferCancelTransactor.h"
|
||||
#include "OfferCreateTransactor.h"
|
||||
#include "TrustSetTransactor.h"
|
||||
|
||||
SETUP_LOG();
|
||||
|
||||
Transactor::pointer Transactor::makeTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine)
|
||||
{
|
||||
switch(txn.getTxnType())
|
||||
{
|
||||
case ttPAYMENT:
|
||||
return( Transactor::pointer(new PaymentTransactor(txn,params,engine)) );
|
||||
case ttACCOUNT_SET:
|
||||
return( Transactor::pointer(new AccountSetTransactor(txn,params,engine)) );
|
||||
case ttREGULAR_KEY_SET:
|
||||
return( Transactor::pointer(new RegularKeySetTransactor(txn,params,engine)) );
|
||||
case ttTRUST_SET:
|
||||
return( Transactor::pointer(new TrustSetTransactor(txn,params,engine)) );
|
||||
case ttOFFER_CREATE:
|
||||
return( Transactor::pointer(new OfferCreateTransactor(txn,params,engine)) );
|
||||
case ttOFFER_CANCEL:
|
||||
return( Transactor::pointer(new OfferCancelTransactor(txn,params,engine)) );
|
||||
case ttWALLET_ADD:
|
||||
return( Transactor::pointer(new WalletAddTransactor(txn,params,engine)) );
|
||||
default:
|
||||
return(Transactor::pointer());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Transactor::Transactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : mTxn(txn), mParams(params), mEngine(engine)
|
||||
{
|
||||
mHasAuthKey=false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Transactor::calculateFee()
|
||||
{
|
||||
mFeeDue = theConfig.FEE_DEFAULT;
|
||||
}
|
||||
|
||||
TER Transactor::payFee()
|
||||
{
|
||||
STAmount saPaid = mTxn.getTransactionFee();
|
||||
|
||||
// Only check fee is sufficient when the ledger is open.
|
||||
if (isSetBit(mParams, tapOPEN_LEDGER) && saPaid < mFeeDue)
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: insufficient fee";
|
||||
|
||||
return telINSUF_FEE_P;
|
||||
}
|
||||
|
||||
if( !saPaid ) return tesSUCCESS;
|
||||
|
||||
// Deduct the fee, so it's not available during the transaction.
|
||||
// Will only write the account back, if the transaction succeeds.
|
||||
if (mSourceBalance < saPaid)
|
||||
{
|
||||
cLog(lsINFO)
|
||||
<< boost::str(boost::format("applyTransaction: Delay: insufficient balance: balance=%s paid=%s")
|
||||
% mSourceBalance.getText()
|
||||
% saPaid.getText());
|
||||
|
||||
return terINSUF_FEE_B;
|
||||
}
|
||||
|
||||
mSourceBalance -= saPaid;
|
||||
mTxnAccount->setFieldAmount(sfBalance, mSourceBalance);
|
||||
|
||||
return tesSUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
TER Transactor::checkSig()
|
||||
{
|
||||
// Consistency: Check signature
|
||||
// Verify the transaction's signing public key is the key authorized for signing.
|
||||
if (mHasAuthKey && mSigningPubKey.getAccountID() == mTxnAccount->getFieldAccount(sfRegularKey).getAccountID())
|
||||
{
|
||||
// Authorized to continue.
|
||||
nothing();
|
||||
}
|
||||
else if (mSigningPubKey.getAccountID() == mTxnAccountID)
|
||||
{
|
||||
// Authorized to continue.
|
||||
nothing();
|
||||
}
|
||||
else if (mHasAuthKey)
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: Delay: Not authorized to use account.";
|
||||
|
||||
return tefBAD_AUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: Invalid: Not authorized to use account.";
|
||||
|
||||
return temBAD_AUTH_MASTER;
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER Transactor::checkSeq()
|
||||
{
|
||||
uint32 t_seq = mTxn.getSequence();
|
||||
uint32 a_seq = mTxnAccount->getFieldU32(sfSequence);
|
||||
|
||||
cLog(lsTRACE) << "Aseq=" << a_seq << ", Tseq=" << t_seq;
|
||||
|
||||
if (t_seq != a_seq)
|
||||
{
|
||||
if (a_seq < t_seq)
|
||||
{
|
||||
cLog(lsINFO) << "applyTransaction: future sequence number";
|
||||
|
||||
return terPRE_SEQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint256 txID = mTxn.getTransactionID();
|
||||
if (mEngine->getLedger()->hasTransaction(txID))
|
||||
return tefALREADY;
|
||||
}
|
||||
|
||||
cLog(lsWARNING) << "applyTransaction: past sequence number";
|
||||
|
||||
return tefPAST_SEQ;
|
||||
|
||||
}else
|
||||
{
|
||||
mTxnAccount->setFieldU32(sfSequence, t_seq + 1);
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// check stuff before you bother to lock the ledger
|
||||
TER Transactor::preCheck()
|
||||
{
|
||||
|
||||
mTxnAccountID = mTxn.getSourceAccount().getAccountID();
|
||||
if (!mTxnAccountID)
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: bad source id";
|
||||
|
||||
return temINVALID;
|
||||
}
|
||||
|
||||
// Extract signing key
|
||||
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
|
||||
// without going to disk. Each transaction also notes a source account id. This is used to verify that the signing key is
|
||||
// associated with the account.
|
||||
// XXX This could be a lot cleaner to prevent unnecessary copying.
|
||||
mSigningPubKey = RippleAddress::createAccountPublic(mTxn.getSigningPubKey());
|
||||
|
||||
// Consistency: really signed.
|
||||
if ( !isSetBit(mParams, tapNO_CHECK_SIGN) && !mTxn.checkSign(mSigningPubKey))
|
||||
{
|
||||
cLog(lsWARNING) << "applyTransaction: Invalid transaction: bad signature";
|
||||
|
||||
return temINVALID;
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER Transactor::apply()
|
||||
{
|
||||
TER terResult = tesSUCCESS;
|
||||
terResult=preCheck();
|
||||
if(terResult != tesSUCCESS) return(terResult);
|
||||
|
||||
calculateFee();
|
||||
|
||||
boost::recursive_mutex::scoped_lock sl(mEngine->getLedger()->mLock);
|
||||
|
||||
mTxnAccount = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(mTxnAccountID));
|
||||
|
||||
// Find source account
|
||||
// If are only forwarding, due to resource limitations, we might verifying only some transactions, this would be probabilistic.
|
||||
|
||||
if (!mTxnAccount)
|
||||
{
|
||||
cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") %
|
||||
mTxn.getSourceAccount().humanAccountID());
|
||||
|
||||
return terNO_ACCOUNT;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSourceBalance = mTxnAccount->getFieldAmount(sfBalance);
|
||||
mHasAuthKey = mTxnAccount->isFieldPresent(sfRegularKey);
|
||||
}
|
||||
|
||||
terResult=payFee();
|
||||
if(terResult != tesSUCCESS) return(terResult);
|
||||
|
||||
terResult=checkSig();
|
||||
if(terResult != tesSUCCESS) return(terResult);
|
||||
|
||||
terResult=checkSeq();
|
||||
if(terResult != tesSUCCESS) return(terResult);
|
||||
|
||||
mEngine->entryModify(mTxnAccount);
|
||||
|
||||
return doApply();
|
||||
|
||||
}
|
||||
41
src/cpp/ripple/Transactor.h
Normal file
41
src/cpp/ripple/Transactor.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef __TRANSACTOR__
|
||||
#define __TRANSACTOR__
|
||||
|
||||
#include "SerializedTransaction.h"
|
||||
#include "TransactionErr.h"
|
||||
#include "TransactionEngine.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class Transactor
|
||||
{
|
||||
protected:
|
||||
const SerializedTransaction& mTxn;
|
||||
TransactionEngine* mEngine;
|
||||
TransactionEngineParams mParams;
|
||||
|
||||
uint160 mTxnAccountID;
|
||||
STAmount mFeeDue;
|
||||
STAmount mSourceBalance;
|
||||
SLE::pointer mTxnAccount;
|
||||
bool mHasAuthKey;
|
||||
RippleAddress mSigningPubKey;
|
||||
|
||||
|
||||
TER preCheck();
|
||||
TER checkSeq();
|
||||
TER payFee();
|
||||
virtual void calculateFee();
|
||||
virtual TER checkSig();
|
||||
virtual TER doApply()=0;
|
||||
|
||||
Transactor(const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine* engine);
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<Transactor> pointer;
|
||||
|
||||
static Transactor::pointer makeTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine);
|
||||
|
||||
TER apply();
|
||||
};
|
||||
|
||||
#endif
|
||||
149
src/cpp/ripple/TrustSetTransactor.cpp
Normal file
149
src/cpp/ripple/TrustSetTransactor.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "TrustSetTransactor.h"
|
||||
|
||||
TER TrustSetTransactor::doApply()
|
||||
{
|
||||
TER terResult = tesSUCCESS;
|
||||
Log(lsINFO) << "doTrustSet>";
|
||||
|
||||
const STAmount saLimitAmount = mTxn.getFieldAmount(sfLimitAmount);
|
||||
const bool bQualityIn = mTxn.isFieldPresent(sfQualityIn);
|
||||
const uint32 uQualityIn = bQualityIn ? mTxn.getFieldU32(sfQualityIn) : 0;
|
||||
const bool bQualityOut = mTxn.isFieldPresent(sfQualityOut);
|
||||
const uint32 uQualityOut = bQualityIn ? mTxn.getFieldU32(sfQualityOut) : 0;
|
||||
const uint160 uCurrencyID = saLimitAmount.getCurrency();
|
||||
uint160 uDstAccountID = saLimitAmount.getIssuer();
|
||||
const bool bFlipped = mTxnAccountID > uDstAccountID; // true, iff current is not lowest.
|
||||
bool bDelIndex = false;
|
||||
|
||||
// Check if destination makes sense.
|
||||
|
||||
if (saLimitAmount.isNegative())
|
||||
{
|
||||
Log(lsINFO) << "doTrustSet: Malformed transaction: Negatived credit limit.";
|
||||
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (!uDstAccountID || uDstAccountID == ACCOUNT_ONE)
|
||||
{
|
||||
Log(lsINFO) << "doTrustSet: Malformed transaction: Destination account not specified.";
|
||||
|
||||
return temDST_NEEDED;
|
||||
}
|
||||
else if (mTxnAccountID == uDstAccountID)
|
||||
{
|
||||
Log(lsINFO) << "doTrustSet: Malformed transaction: Can not extend credit to self.";
|
||||
|
||||
return temDST_IS_SRC;
|
||||
}
|
||||
|
||||
SLE::pointer sleDst = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
if (!sleDst)
|
||||
{
|
||||
Log(lsINFO) << "doTrustSet: Delay transaction: Destination account does not exist.";
|
||||
|
||||
return terNO_DST;
|
||||
}
|
||||
|
||||
STAmount saLimitAllow = saLimitAmount;
|
||||
saLimitAllow.setIssuer(mTxnAccountID);
|
||||
|
||||
SLE::pointer sleRippleState = mEngine->entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(mTxnAccountID, uDstAccountID, uCurrencyID));
|
||||
if (sleRippleState)
|
||||
{
|
||||
// A line exists in one or more directions.
|
||||
#if 0
|
||||
if (!saLimitAmount)
|
||||
{
|
||||
// Zeroing line.
|
||||
uint160 uLowID = sleRippleState->getFieldAmount(sfLowLimit).getIssuer();
|
||||
uint160 uHighID = sleRippleState->getFieldAmount(sfHighLimit).getIssuer();
|
||||
bool bLow = uLowID == uSrcAccountID;
|
||||
bool bHigh = uLowID == uDstAccountID;
|
||||
bool bBalanceZero = !sleRippleState->getFieldAmount(sfBalance);
|
||||
STAmount saDstLimit = sleRippleState->getFieldAmount(bSendLow ? sfLowLimit : sfHighLimit);
|
||||
bool bDstLimitZero = !saDstLimit;
|
||||
|
||||
assert(bLow || bHigh);
|
||||
|
||||
if (bBalanceZero && bDstLimitZero)
|
||||
{
|
||||
// Zero balance and eliminating last limit.
|
||||
|
||||
bDelIndex = true;
|
||||
terResult = dirDelete(false, uSrcRef, Ledger::getOwnerDirIndex(mTxnAccountID), sleRippleState->getIndex(), false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!bDelIndex)
|
||||
{
|
||||
sleRippleState->setFieldAmount(bFlipped ? sfHighLimit: sfLowLimit, saLimitAllow);
|
||||
|
||||
if (!bQualityIn)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
else if (uQualityIn)
|
||||
{
|
||||
sleRippleState->setFieldU32(bFlipped ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
sleRippleState->makeFieldAbsent(bFlipped ? sfLowQualityIn : sfHighQualityIn);
|
||||
}
|
||||
|
||||
if (!bQualityOut)
|
||||
{
|
||||
nothing();
|
||||
}
|
||||
else if (uQualityOut)
|
||||
{
|
||||
sleRippleState->setFieldU32(bFlipped ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
sleRippleState->makeFieldAbsent(bFlipped ? sfLowQualityOut : sfHighQualityOut);
|
||||
}
|
||||
|
||||
mEngine->entryModify(sleRippleState);
|
||||
}
|
||||
|
||||
Log(lsINFO) << "doTrustSet: Modifying ripple line: bDelIndex=" << bDelIndex;
|
||||
}
|
||||
// Line does not exist.
|
||||
else if (!saLimitAmount)
|
||||
{
|
||||
Log(lsINFO) << "doTrustSet: Redundant: Setting non-existent ripple line to 0.";
|
||||
|
||||
return terNO_LINE_NO_ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new ripple line.
|
||||
sleRippleState = mEngine->entryCreate(ltRIPPLE_STATE, Ledger::getRippleStateIndex(mTxnAccountID, uDstAccountID, uCurrencyID));
|
||||
|
||||
Log(lsINFO) << "doTrustSet: Creating ripple line: " << sleRippleState->getIndex().ToString();
|
||||
|
||||
sleRippleState->setFieldAmount(sfBalance, STAmount(uCurrencyID, ACCOUNT_ONE)); // Zero balance in currency.
|
||||
sleRippleState->setFieldAmount(bFlipped ? sfHighLimit : sfLowLimit, saLimitAllow);
|
||||
sleRippleState->setFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, uDstAccountID));
|
||||
|
||||
if (uQualityIn)
|
||||
sleRippleState->setFieldU32(bFlipped ? sfHighQualityIn : sfLowQualityIn, uQualityIn);
|
||||
if (uQualityOut)
|
||||
sleRippleState->setFieldU32(bFlipped ? sfHighQualityOut : sfLowQualityOut, uQualityOut);
|
||||
|
||||
uint64 uSrcRef; // Ignored, dirs never delete.
|
||||
|
||||
terResult = mEngine->getNodes().dirAdd(uSrcRef, Ledger::getOwnerDirIndex(mTxnAccountID), sleRippleState->getIndex());
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
terResult = mEngine->getNodes().dirAdd(uSrcRef, Ledger::getOwnerDirIndex(uDstAccountID), sleRippleState->getIndex());
|
||||
}
|
||||
|
||||
Log(lsINFO) << "doTrustSet<";
|
||||
|
||||
return terResult;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
9
src/cpp/ripple/TrustSetTransactor.h
Normal file
9
src/cpp/ripple/TrustSetTransactor.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "Transactor.h"
|
||||
|
||||
class TrustSetTransactor : public Transactor
|
||||
{
|
||||
public:
|
||||
TrustSetTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
|
||||
TER doApply();
|
||||
};
|
||||
58
src/cpp/ripple/WalletAddTransactor.cpp
Normal file
58
src/cpp/ripple/WalletAddTransactor.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "WalletAddTransactor.h"
|
||||
|
||||
TER WalletAddTransactor::doApply()
|
||||
{
|
||||
std::cerr << "WalletAdd>" << std::endl;
|
||||
|
||||
const std::vector<unsigned char> vucPubKey = mTxn.getFieldVL(sfPublicKey);
|
||||
const std::vector<unsigned char> vucSignature = mTxn.getFieldVL(sfSignature);
|
||||
const uint160 uAuthKeyID = mTxn.getFieldAccount160(sfRegularKey);
|
||||
const RippleAddress naMasterPubKey = RippleAddress::createAccountPublic(vucPubKey);
|
||||
const uint160 uDstAccountID = naMasterPubKey.getAccountID();
|
||||
|
||||
// FIXME: This should be moved to the transaction's signature check logic and cached
|
||||
if (!naMasterPubKey.accountPublicVerify(Serializer::getSHA512Half(uAuthKeyID.begin(), uAuthKeyID.size()), vucSignature))
|
||||
{
|
||||
std::cerr << "WalletAdd: unauthorized: bad signature " << std::endl;
|
||||
|
||||
return tefBAD_ADD_AUTH;
|
||||
}
|
||||
|
||||
SLE::pointer sleDst = mEngine->entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
|
||||
if (sleDst)
|
||||
{
|
||||
std::cerr << "WalletAdd: account already created" << std::endl;
|
||||
|
||||
return tefCREATED;
|
||||
}
|
||||
|
||||
STAmount saAmount = mTxn.getFieldAmount(sfAmount);
|
||||
STAmount saSrcBalance = mTxnAccount->getFieldAmount(sfBalance);
|
||||
|
||||
if (saSrcBalance < saAmount)
|
||||
{
|
||||
std::cerr
|
||||
<< boost::str(boost::format("WalletAdd: Delay transaction: insufficient balance: balance=%s amount=%s")
|
||||
% saSrcBalance.getText()
|
||||
% saAmount.getText())
|
||||
<< std::endl;
|
||||
|
||||
return terUNFUNDED;
|
||||
}
|
||||
|
||||
// Deduct initial balance from source account.
|
||||
mTxnAccount->setFieldAmount(sfBalance, saSrcBalance-saAmount);
|
||||
|
||||
// Create the account.
|
||||
sleDst = mEngine->entryCreate(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
|
||||
|
||||
sleDst->setFieldAccount(sfAccount, uDstAccountID);
|
||||
sleDst->setFieldU32(sfSequence, 1);
|
||||
sleDst->setFieldAmount(sfBalance, saAmount);
|
||||
sleDst->setFieldAccount(sfRegularKey, uAuthKeyID);
|
||||
|
||||
std::cerr << "WalletAdd<" << std::endl;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
10
src/cpp/ripple/WalletAddTransactor.h
Normal file
10
src/cpp/ripple/WalletAddTransactor.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "Transactor.h"
|
||||
|
||||
|
||||
class WalletAddTransactor : public Transactor
|
||||
{
|
||||
public:
|
||||
WalletAddTransactor(const SerializedTransaction& txn,TransactionEngineParams params, TransactionEngine* engine) : Transactor(txn,params,engine) {}
|
||||
|
||||
TER doApply();
|
||||
};
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define QUALITY_ONE 1000000000 // 10e9
|
||||
@@ -41,6 +40,13 @@ extern uint32_t be32toh(uint32_t value);
|
||||
#define htole64(x) OSSwapHostToLittleInt64(x)
|
||||
#define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <sys/types.h>
|
||||
#define be16toh(x) betoh16(x)
|
||||
#define be32toh(x) betoh32(x)
|
||||
#define be64toh(x) betoh64(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ UInt160.prototype.to_json = function () {
|
||||
return output;
|
||||
};
|
||||
|
||||
// XXX Internal form should be UInt160.
|
||||
var Currency = function () {
|
||||
// Internal form: 0 = XRP. 3 letter-code.
|
||||
// XXX Internal should be 0 or hex with three letter annotation when valid.
|
||||
@@ -251,6 +252,11 @@ Currency.prototype.copyTo = function(d) {
|
||||
return d;
|
||||
};
|
||||
|
||||
Currency.prototype.equals = function(d) {
|
||||
return ('string' !== typeof this._value && isNaN(this._value))
|
||||
|| ('string' !== typeof d._value && isNaN(d._value)) ? false : this._value === d._value;
|
||||
}
|
||||
|
||||
// this._value = NaN on error.
|
||||
Currency.prototype.parse_json = function(j) {
|
||||
if ("" === j || "0" === j || "XRP" === j) {
|
||||
@@ -591,6 +597,7 @@ Amount.prototype.parse_issuer = function (issuer) {
|
||||
};
|
||||
|
||||
// Check BigInteger NaN
|
||||
// Checks currency, does not check issuer.
|
||||
Amount.prototype.equals = function (d) {
|
||||
return 'string' === typeof (d)
|
||||
? this.equals(Amount.from_json(d))
|
||||
@@ -599,9 +606,35 @@ Amount.prototype.equals = function (d) {
|
||||
&& this._is_native === d._is_native
|
||||
&& (this._is_native
|
||||
? this._value.equals(d._value)
|
||||
: this._is_negative === d._is_negative
|
||||
? this._value.equals(d._value)
|
||||
: this._value.equals(BigInteger.ZERO) && d._value.equals(BigInteger.ZERO)));
|
||||
: this._currency.equals(d._currency)
|
||||
? this._is_negative === d._is_negative
|
||||
? this._value.equals(d._value)
|
||||
: this._value.equals(BigInteger.ZERO) && d._value.equals(BigInteger.ZERO)
|
||||
: false));
|
||||
};
|
||||
|
||||
Amount.prototype.not_equals_why = function (d) {
|
||||
return 'string' === typeof (d)
|
||||
? this.not_equals_why(Amount.from_json(d))
|
||||
: this === d
|
||||
? false
|
||||
: d.constructor === Amount
|
||||
? this._is_native === d._is_native
|
||||
? this._is_native
|
||||
? this._value.equals(d._value)
|
||||
? false
|
||||
: "XRP value differs."
|
||||
: this._currency.equals(d._currency)
|
||||
? this._is_negative === d._is_negative
|
||||
? this._value.equals(d._value)
|
||||
? false
|
||||
: this._value.equals(BigInteger.ZERO) && d._value.equals(BigInteger.ZERO)
|
||||
? false
|
||||
: "Non-XRP value differs."
|
||||
: "Non-XRP sign differs."
|
||||
: "Non-XRP currency differs (" + JSON.stringify(this._currency) + "/" + JSON.stringify(d._currency) + ")"
|
||||
: "Native mismatch"
|
||||
: "Wrong constructor."
|
||||
};
|
||||
|
||||
exports.Amount = Amount;
|
||||
|
||||
@@ -21,7 +21,7 @@ var EventEmitter = require('events').EventEmitter;
|
||||
var Amount = require('./amount.js').Amount;
|
||||
var UInt160 = require('./amount.js').UInt160;
|
||||
|
||||
// Request events emmitted:
|
||||
// Request events emitted:
|
||||
// 'success' : Request successful.
|
||||
// 'error' : Request failed.
|
||||
// 'remoteError'
|
||||
@@ -166,22 +166,22 @@ Request.prototype.accounts = function (accounts) {
|
||||
// Remote - access to a remote Ripple server via websocket.
|
||||
//
|
||||
// Events:
|
||||
// 'connectted'
|
||||
// 'connected'
|
||||
// 'disconnected'
|
||||
// 'state':
|
||||
// - 'online' : connectted and subscribed
|
||||
// - 'offline' : not subscribed or not connectted.
|
||||
// - 'online' : connected and subscribed
|
||||
// - 'offline' : not subscribed or not connected.
|
||||
// 'ledger_closed': A good indicate of ready to serve.
|
||||
// 'subscribed' : This indicates stand-alone is available.
|
||||
//
|
||||
|
||||
// --> trusted: truthy, if remote is trusted
|
||||
var Remote = function (trusted, websocket_ip, websocket_port, trace) {
|
||||
this.trusted = trusted;
|
||||
this.websocket_ip = websocket_ip;
|
||||
this.websocket_port = websocket_port;
|
||||
var Remote = function (opts, trace) {
|
||||
this.trusted = opts.trusted;
|
||||
this.websocket_ip = opts.websocket_ip;
|
||||
this.websocket_port = opts.websocket_port;
|
||||
this.id = 0;
|
||||
this.trace = trace;
|
||||
this.trace = opts.trace || trace;
|
||||
this._ledger_current_index = undefined;
|
||||
this._ledger_hash = undefined;
|
||||
this._ledger_time = undefined;
|
||||
@@ -219,10 +219,10 @@ var Remote = function (trusted, websocket_ip, websocket_port, trace) {
|
||||
|
||||
Remote.prototype = new EventEmitter;
|
||||
|
||||
Remote.from_config = function (name, trace) {
|
||||
var serverConfig = exports.config.servers[name];
|
||||
Remote.from_config = function (obj, trace) {
|
||||
var serverConfig = 'string' === typeof obj ? exports.config.servers[obj] : obj;
|
||||
|
||||
var remote = new Remote(serverConfig.trusted, serverConfig.websocket_ip, serverConfig.websocket_port, trace);
|
||||
var remote = new Remote(serverConfig, trace);
|
||||
|
||||
for (var account in exports.config.accounts) {
|
||||
var accountInfo = exports.config.accounts[account];
|
||||
@@ -268,7 +268,7 @@ Remote.fees = {
|
||||
'offer' : Amount.from_json("10"),
|
||||
};
|
||||
|
||||
// Set the emited state: 'online' or 'offline'
|
||||
// Set the emitted state: 'online' or 'offline'
|
||||
Remote.prototype._set_state = function (state) {
|
||||
if (this.trace) console.log("remote: set_state: %s", state);
|
||||
|
||||
@@ -450,12 +450,12 @@ Remote.prototype._connect_message = function (ws, json) {
|
||||
unexpected = true;
|
||||
}
|
||||
else if ('success' === message.status) {
|
||||
if (this.trace) console.log("remote: response: %s", json);
|
||||
if (this.trace) console.log("remote: response: %s", JSON.stringify(message, undefined, 2));
|
||||
|
||||
request.emit('success', message.result);
|
||||
}
|
||||
else if (message.error) {
|
||||
if (this.trace) console.log("remote: error: %s", json);
|
||||
if (this.trace) console.log("remote: error: %s", JSON.stringify(message, undefined, 2));
|
||||
|
||||
request.emit('error', {
|
||||
'error' : 'remoteError',
|
||||
@@ -700,7 +700,7 @@ Remote.prototype.submit = function (transaction) {
|
||||
if (transaction.secret && !this.trusted)
|
||||
{
|
||||
transaction.emit('error', {
|
||||
'result' : 'serverUntrusted',
|
||||
'result' : 'tejServerUntrusted',
|
||||
'result_message' : "Attempt to give a secret to an untrusted server."
|
||||
});
|
||||
}
|
||||
@@ -1026,6 +1026,7 @@ var SUBMIT_LOST = 8; // Give up tracking.
|
||||
var Transaction = function (remote) {
|
||||
var self = this;
|
||||
|
||||
this.callback = undefined;
|
||||
this.remote = remote;
|
||||
this.secret = undefined;
|
||||
this.build_path = true;
|
||||
@@ -1108,14 +1109,25 @@ Transaction.prototype.set_state = function (state) {
|
||||
// XXX Don't allow a submit without knowing ledger_index.
|
||||
// XXX Have a network canSubmit(), post events for following.
|
||||
// XXX Also give broader status for tracking through network disconnects.
|
||||
Transaction.prototype.submit = function () {
|
||||
// callback = function (status, info) {
|
||||
// // status is final status. Only works under a ledger_accepting conditions.
|
||||
// switch status:
|
||||
// case 'tesSUCCESS': all is well.
|
||||
// case 'tejServerUntrusted': sending secret to untrusted server.
|
||||
// case 'tejInvalidAccount': locally detected error.
|
||||
// case 'tejLost': locally gave up looking
|
||||
// default: some other TER
|
||||
// }
|
||||
Transaction.prototype.submit = function (callback) {
|
||||
var self = this;
|
||||
var tx_json = this.tx_json;
|
||||
|
||||
this.callback = callback;
|
||||
|
||||
if ('string' !== typeof tx_json.Account)
|
||||
{
|
||||
this.emit('error', {
|
||||
'error' : 'invalidAccount',
|
||||
(this.callback || this.emit)('error', {
|
||||
'error' : 'tejInvalidAccount',
|
||||
'error_message' : 'Bad account.'
|
||||
});
|
||||
return;
|
||||
@@ -1134,11 +1146,12 @@ Transaction.prototype.submit = function () {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.listeners('final').length || this.listeners('lost').length || this.listeners('pending').length) {
|
||||
// There are listeners for 'final', 'lost', or 'pending' arrange to emit them.
|
||||
if (this.callback || this.listeners('final').length || this.listeners('lost').length || this.listeners('pending').length) {
|
||||
// There are listeners for callback, 'final', 'lost', or 'pending' arrange to emit them.
|
||||
|
||||
this.submit_index = this.remote._ledger_current_index;
|
||||
|
||||
// When a ledger closes, look for the result.
|
||||
var on_ledger_closed = function (ledger_hash, ledger_index) {
|
||||
var stop = false;
|
||||
|
||||
@@ -1148,6 +1161,11 @@ Transaction.prototype.submit = function () {
|
||||
.on('success', function (message) {
|
||||
self.set_state(message.metadata.TransactionResult);
|
||||
self.emit('final', message);
|
||||
|
||||
if (self.callback)
|
||||
self.callback(message.metadata.TransactionResult, message);
|
||||
|
||||
stop = true;
|
||||
})
|
||||
.on('error', function (message) {
|
||||
if ('remoteError' === message.error
|
||||
@@ -1155,6 +1173,10 @@ Transaction.prototype.submit = function () {
|
||||
if (self.submit_index + SUBMIT_LOST < ledger_index) {
|
||||
self.set_state('client_lost'); // Gave up.
|
||||
self.emit('lost');
|
||||
|
||||
if (self.callback)
|
||||
self.callback('tejLost', message);
|
||||
|
||||
stop = true;
|
||||
}
|
||||
else if (self.submit_index + SUBMIT_MISSING < ledger_index) {
|
||||
@@ -1170,12 +1192,18 @@ Transaction.prototype.submit = function () {
|
||||
.request();
|
||||
|
||||
if (stop) {
|
||||
self.removeListener('ledger_closed', on_ledger_closed);
|
||||
self.remote.removeListener('ledger_closed', on_ledger_closed);
|
||||
self.emit('final', message);
|
||||
}
|
||||
};
|
||||
|
||||
this.remote.on('ledger_closed', on_ledger_closed);
|
||||
|
||||
if (this.callback) {
|
||||
this.on('error', function (message) {
|
||||
self.callback(message.error, message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.set_state('client_submitted');
|
||||
@@ -1355,7 +1383,7 @@ Transaction.prototype.password_fund = function (src, dst) {
|
||||
Transaction.prototype.password_set = function (src, authorized_key, generator, public_key, signature) {
|
||||
this.secret = this._account_secret(src);
|
||||
this.tx_json.TransactionType = 'PasswordSet';
|
||||
this.tx_json.AuthorizedKey = authorized_key;
|
||||
this.tx_json.RegularKey = authorized_key;
|
||||
this.tx_json.Generator = generator;
|
||||
this.tx_json.PublicKey = public_key;
|
||||
this.tx_json.Signature = signature;
|
||||
@@ -1412,7 +1440,7 @@ Transaction.prototype.wallet_add = function (src, amount, authorized_key, public
|
||||
this.secret = this._account_secret(src);
|
||||
this.tx_json.TransactionType = 'WalletAdd';
|
||||
this.tx_json.Amount = Amount.json_rewrite(amount);
|
||||
this.tx_json.AuthorizedKey = authorized_key;
|
||||
this.tx_json.RegularKey = authorized_key;
|
||||
this.tx_json.PublicKey = public_key;
|
||||
this.tx_json.Signature = signature;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var path = require("path");
|
||||
|
||||
// Where to find the binary.
|
||||
exports.rippled = path.join(process.cwd(), "build/rippled");
|
||||
exports.rippled = path.resolve("build/rippled");
|
||||
|
||||
exports.server_default = "alpha";
|
||||
|
||||
@@ -534,5 +534,87 @@ buster.testCase("Offer tests", {
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
"ripple cross currency payment" :
|
||||
// alice --> [XRP --> carol --> USD/mtgox] --> bob
|
||||
|
||||
function (done) {
|
||||
var self = this;
|
||||
var seq;
|
||||
|
||||
// self.remote.set_trace();
|
||||
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
self.what = "Create accounts.";
|
||||
|
||||
testutils.create_accounts(self.remote, "root", "10000", ["alice", "bob", "carol", "mtgox"], callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Set limits.";
|
||||
|
||||
testutils.credit_limits(self.remote,
|
||||
{
|
||||
"carol" : "1000/USD/mtgox",
|
||||
"bob" : "2000/USD/mtgox"
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Distribute funds.";
|
||||
|
||||
testutils.payments(self.remote,
|
||||
{
|
||||
"mtgox" : "500/USD/carol"
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Create offer.";
|
||||
|
||||
self.remote.transaction()
|
||||
.offer_create("carol", "500", "50/USD/mtgox")
|
||||
.on('proposed', function (m) {
|
||||
// console.log("PROPOSED: offer_create: %s", JSON.stringify(m));
|
||||
callback(m.result !== 'tesSUCCESS');
|
||||
|
||||
seq = m.tx_json.Sequence;
|
||||
})
|
||||
.submit();
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Alice send USD/mtgox converting from XRP.";
|
||||
|
||||
self.remote.transaction()
|
||||
.payment("alice", "bob", "25/USD/mtgox")
|
||||
.send_max("333")
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
callback(m.result !== 'tesSUCCESS');
|
||||
})
|
||||
.submit();
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Verify balances.";
|
||||
|
||||
testutils.verify_balances(self.remote,
|
||||
{
|
||||
// "alice" : [ "500" ],
|
||||
"bob" : "25/USD/mtgox",
|
||||
"carol" : "475/USD/mtgox",
|
||||
},
|
||||
callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Verify offer consumed.";
|
||||
|
||||
testutils.verify_offer_not_found(self.remote, "bob", seq, callback);
|
||||
},
|
||||
], function (error) {
|
||||
buster.refute(error, self.what);
|
||||
done();
|
||||
});
|
||||
},
|
||||
});
|
||||
// vim:sw=2:sts=2:ts=8
|
||||
|
||||
@@ -15,11 +15,34 @@ var serverDelay = 1500;
|
||||
|
||||
buster.testRunner.timeout = 5000;
|
||||
|
||||
/*
|
||||
buster.testCase("Simple", {
|
||||
'setUp' : testutils.build_setup({no_server: true}), //
|
||||
'tearDown' : testutils.build_teardown(),
|
||||
|
||||
"simple." :
|
||||
function (done) { buster.assert(1);
|
||||
|
||||
this.remote.transaction()
|
||||
.payment('root', 'alice', "10000")
|
||||
.on('success', function (r) {
|
||||
done();
|
||||
}).submit();
|
||||
|
||||
this.remote.transaction()
|
||||
.payment('root', 'alice', "20000")
|
||||
.on('success', function (r) {
|
||||
done();
|
||||
}).submit();
|
||||
|
||||
}
|
||||
}); */
|
||||
|
||||
buster.testCase("Sending", {
|
||||
'setUp' : testutils.build_setup(),
|
||||
'tearDown' : testutils.build_teardown(),
|
||||
|
||||
"send XRP to non-existant account without create." :
|
||||
"send XRP to non-existent account without create." :
|
||||
function (done) {
|
||||
var self = this;
|
||||
var ledgers = 20;
|
||||
@@ -77,12 +100,12 @@ buster.testCase("Sending", {
|
||||
},
|
||||
|
||||
// Also test transaction becomes lost after terNO_DST.
|
||||
"credit_limit to non-existant account = terNO_DST" :
|
||||
"credit_limit to non-existent account = terNO_DST" :
|
||||
function (done) {
|
||||
this.remote.transaction()
|
||||
.ripple_line_set("root", "100/USD/alice")
|
||||
.on('proposed', function (m) {
|
||||
// console.log("proposed: %s", JSON.stringify(m));
|
||||
//console.log("proposed: %s", JSON.stringify(m));
|
||||
|
||||
buster.assert.equals(m.result, 'terNO_DST');
|
||||
|
||||
@@ -102,7 +125,7 @@ buster.testCase("Sending", {
|
||||
testutils.create_accounts(self.remote, "root", "10000", ["alice", "bob", "mtgox"], callback);
|
||||
},
|
||||
function (callback) {
|
||||
self.what = "Check a non-existant credit limit.";
|
||||
self.what = "Check a non-existent credit limit.";
|
||||
|
||||
self.remote.request_ripple_balance("alice", "mtgox", "USD", 'CURRENT')
|
||||
.on('ripple_state', function (m) {
|
||||
|
||||
@@ -52,7 +52,7 @@ Server.prototype.once = function (e, c) {
|
||||
};
|
||||
|
||||
Server.prototype.serverPath = function() {
|
||||
return "tmp/server/" + this.name;
|
||||
return path.resolve("tmp/server", this.name);
|
||||
};
|
||||
|
||||
Server.prototype.configPath = function() {
|
||||
|
||||
@@ -22,7 +22,7 @@ var account_dump = function (remote, account, callback) {
|
||||
.ledger_hash(remote.ledger_hash())
|
||||
.account_root("root")
|
||||
.on('success', function (r) {
|
||||
console.log("account_root: %s", JSON.stringify(r, undefined, 2));
|
||||
//console.log("account_root: %s", JSON.stringify(r, undefined, 2));
|
||||
|
||||
callback();
|
||||
})
|
||||
@@ -106,7 +106,10 @@ var build_setup = function (opts, host) {
|
||||
* @param host {String} Identifier for the host configuration to be used.
|
||||
*/
|
||||
var build_teardown = function (host) {
|
||||
|
||||
return function (done) {
|
||||
|
||||
|
||||
host = host || config.server_default;
|
||||
|
||||
var data = this.store[host];
|
||||
@@ -114,16 +117,22 @@ var build_teardown = function (host) {
|
||||
|
||||
async.series([
|
||||
function disconnectWebsocketStep(callback) {
|
||||
|
||||
data.remote
|
||||
.on('disconnected', callback)
|
||||
.connect(false);
|
||||
},
|
||||
function stopServerStep(callback) {
|
||||
if (opts.no_server) return callback();
|
||||
|
||||
if (opts.no_server)
|
||||
{
|
||||
|
||||
return callback();
|
||||
}
|
||||
|
||||
data.server.on('stopped', callback).stop();
|
||||
}
|
||||
], done);
|
||||
], done);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -265,16 +274,16 @@ var verify_balance = function (remote, src, amount_json, callback) {
|
||||
else {
|
||||
remote.request_ripple_balance(src, amount.issuer().to_json(), amount.currency().to_json(), 'CURRENT')
|
||||
.once('ripple_state', function (m) {
|
||||
// console.log("BALANCE: %s", JSON.stringify(m));
|
||||
// console.log("account_balance: %s", m.account_balance.to_text_full());
|
||||
// console.log("account_limit: %s", m.account_limit.to_text_full());
|
||||
// console.log("issuer_balance: %s", m.issuer_balance.to_text_full());
|
||||
// console.log("issuer_limit: %s", m.issuer_limit.to_text_full());
|
||||
// console.log("BALANCE: %s", JSON.stringify(m));
|
||||
// console.log("account_balance: %s", m.account_balance.to_text_full());
|
||||
// console.log("account_limit: %s", m.account_limit.to_text_full());
|
||||
// console.log("issuer_balance: %s", m.issuer_balance.to_text_full());
|
||||
// console.log("issuer_limit: %s", m.issuer_limit.to_text_full());
|
||||
|
||||
var account_balance = Amount.from_json(m.account_balance);
|
||||
|
||||
if (!account_balance.equals(amount)) {
|
||||
console.log("verify_balance: failed: %s vs %s is %s", src, amount_json, amount.to_text_full());
|
||||
console.log("verify_balance: failed: %s vs %s is %s: %s", src, account_balance.to_text_full(), amount.to_text_full(), account_balance.not_equals_why(amount));
|
||||
}
|
||||
|
||||
callback(!account_balance.equals(amount));
|
||||
|
||||
@@ -2,6 +2,7 @@ var buster = require("buster");
|
||||
|
||||
var Server = require("./server.js").Server;
|
||||
var Remote = require("../src/js/remote.js").Remote;
|
||||
var config = require("./config.js");
|
||||
|
||||
require("../src/js/remote.js").config = require("./config.js");
|
||||
|
||||
@@ -9,10 +10,10 @@ buster.testRunner.timeout = 5000;
|
||||
|
||||
buster.testCase("WebSocket connection", {
|
||||
'setUp' :
|
||||
function (done) { server = Server.from_config("alpha").on('started', done).start(); },
|
||||
function (done) { if (config.servers.alpha.no_server) done(); else server = Server.from_config("alpha").on('started', done).start(); },
|
||||
|
||||
'tearDown' :
|
||||
function (done) { server.on('stopped', done).stop(); },
|
||||
function (done) { if (config.servers.alpha.no_server) done(); else server.on('stopped', done).stop(); },
|
||||
|
||||
"websocket connect and disconnect" :
|
||||
function (done) {
|
||||
|
||||
Reference in New Issue
Block a user