Transactor refactor:

* Allocate transactors on the stack instead of the heap.
* Remove header files and reduce transactor public interface.
This commit is contained in:
Nik Bougalis
2014-09-04 15:12:23 -07:00
parent 624a803955
commit 889c0a0d0f
25 changed files with 2079 additions and 2462 deletions

View File

@@ -126,8 +126,6 @@
</ClCompile>
<ClInclude Include="..\..\build\proto\ripple.pb.h">
</ClInclude>
<ClInclude Include="..\..\src\BeastConfig.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\Arithmetic.h">
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\asio\abstract_socket.cpp">
@@ -304,14 +302,14 @@
<ClCompile Include="..\..\src\beast\beast\crypto\impl\MurmurHash.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\Sha256.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\sha2\sha2.c">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\beast\beast\crypto\impl\sha2\sha2.h">
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\Sha256.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\UnsignedInteger.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -826,14 +824,6 @@
</ClCompile>
<ClInclude Include="..\..\src\beast\beast\module\core\text\StringPairArray.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\CriticalSection.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\DynamicLibrary.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\Process.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\ScopedLock.h">
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\module\core\thread\DeadlineTimer.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -846,6 +836,14 @@
</ClCompile>
<ClInclude Include="..\..\src\beast\beast\module\core\thread\Workers.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\CriticalSection.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\DynamicLibrary.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\Process.h">
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\ScopedLock.h">
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\module\core\time\AtExitHook.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -1188,6 +1186,8 @@
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\Version.h">
</ClInclude>
<ClInclude Include="..\..\src\BeastConfig.h">
</ClInclude>
<ClCompile Include="..\..\src\hyperleveldb\db\builder.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -2386,53 +2386,33 @@
<ClCompile Include="..\..\src\ripple\module\app\transactors\AddWallet.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\AddWallet.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CancelOffer.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CancelOffer.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\Change.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\Change.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOffer.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CreateOffer.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOfferBridged.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CreateOfferBridged.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOfferDirect.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CreateOfferDirect.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\Payment.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\Payment.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\SetAccount.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\SetAccount.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\SetRegularKey.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\SetRegularKey.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\SetTrust.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\SetTrust.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\Transactor.cpp">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -3943,57 +3923,6 @@
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\third-party\rapidjson\reader.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\backupable\backupable_db.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\document_db.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\json_document.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.h">
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\put.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\uint64add.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\redis\redis_lists.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_lists.h">
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_exception.h">
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_iterator.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\spatialdb\spatial_db.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\spatialdb\utils.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\util\arena.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
@@ -4167,6 +4096,57 @@
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\util\xxhash.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\backupable\backupable_db.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\document_db.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\json_document.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.h">
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\put.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\uint64add.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\redis\redis_lists.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_lists.h">
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_exception.h">
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_iterator.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\spatialdb\spatial_db.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\spatialdb\utils.h">
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.cc">
<ExcludedFromBuild>True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.h">
</ClInclude>
<ClInclude Include="..\..\src\snappy\config\snappy-stubs-public.h">
</ClInclude>
<ClInclude Include="..\..\src\snappy\snappy\snappy-internal.h">

View File

@@ -666,9 +666,6 @@
<ClInclude Include="..\..\build\proto\ripple.pb.h">
<Filter>build\proto</Filter>
</ClInclude>
<ClInclude Include="..\..\src\BeastConfig.h">
<Filter>.</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\Arithmetic.h">
<Filter>beast</Filter>
</ClInclude>
@@ -900,15 +897,15 @@
<ClCompile Include="..\..\src\beast\beast\crypto\impl\MurmurHash.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\Sha256.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\sha2\sha2.c">
<Filter>beast\crypto\impl\sha2</Filter>
</ClCompile>
<ClInclude Include="..\..\src\beast\beast\crypto\impl\sha2\sha2.h">
<Filter>beast\crypto\impl\sha2</Filter>
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\Sha256.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\beast\beast\crypto\impl\UnsignedInteger.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
@@ -1554,18 +1551,6 @@
<ClInclude Include="..\..\src\beast\beast\module\core\text\StringPairArray.h">
<Filter>beast\module\core\text</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\CriticalSection.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\DynamicLibrary.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\Process.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\ScopedLock.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\module\core\thread\DeadlineTimer.cpp">
<Filter>beast\module\core\thread</Filter>
</ClCompile>
@@ -1581,6 +1566,18 @@
<ClInclude Include="..\..\src\beast\beast\module\core\thread\Workers.h">
<Filter>beast\module\core\thread</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\CriticalSection.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\DynamicLibrary.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\Process.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClInclude Include="..\..\src\beast\beast\module\core\threads\ScopedLock.h">
<Filter>beast\module\core\threads</Filter>
</ClInclude>
<ClCompile Include="..\..\src\beast\beast\module\core\time\AtExitHook.cpp">
<Filter>beast\module\core\time</Filter>
</ClCompile>
@@ -2019,6 +2016,9 @@
<ClInclude Include="..\..\src\beast\beast\Version.h">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\src\BeastConfig.h">
<Filter>.</Filter>
</ClInclude>
<ClCompile Include="..\..\src\hyperleveldb\db\builder.cc">
<Filter>hyperleveldb\db</Filter>
</ClCompile>
@@ -3489,63 +3489,33 @@
<ClCompile Include="..\..\src\ripple\module\app\transactors\AddWallet.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\AddWallet.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CancelOffer.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CancelOffer.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\Change.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\Change.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOffer.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CreateOffer.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOfferBridged.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CreateOfferBridged.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOfferDirect.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\CreateOfferDirect.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\Payment.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\Payment.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\SetAccount.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\SetAccount.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\SetRegularKey.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\SetRegularKey.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\SetTrust.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\module\app\transactors\SetTrust.h">
<Filter>ripple\module\app\transactors</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\module\app\transactors\Transactor.cpp">
<Filter>ripple\module\app\transactors</Filter>
</ClCompile>
@@ -5412,66 +5382,6 @@
<ClInclude Include="..\..\src\rocksdb2\third-party\rapidjson\reader.h">
<Filter>rocksdb2\third-party\rapidjson</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\backupable\backupable_db.cc">
<Filter>rocksdb2\utilities\backupable</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\document_db.cc">
<Filter>rocksdb2\utilities\document</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\json_document.cc">
<Filter>rocksdb2\utilities\document</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.cc">
<Filter>rocksdb2\utilities\geodb</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.h">
<Filter>rocksdb2\utilities\geodb</Filter>
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators.h">
<Filter>rocksdb2\utilities</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\put.cc">
<Filter>rocksdb2\utilities\merge_operators</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.cc">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.h">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.cc">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.h">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\uint64add.cc">
<Filter>rocksdb2\utilities\merge_operators</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\redis\redis_lists.cc">
<Filter>rocksdb2\utilities\redis</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_lists.h">
<Filter>rocksdb2\utilities\redis</Filter>
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_exception.h">
<Filter>rocksdb2\utilities\redis</Filter>
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_iterator.h">
<Filter>rocksdb2\utilities\redis</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\spatialdb\spatial_db.cc">
<Filter>rocksdb2\utilities\spatialdb</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\spatialdb\utils.h">
<Filter>rocksdb2\utilities\spatialdb</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.cc">
<Filter>rocksdb2\utilities\ttl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.h">
<Filter>rocksdb2\utilities\ttl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\util\arena.cc">
<Filter>rocksdb2\util</Filter>
</ClCompile>
@@ -5676,6 +5586,66 @@
<ClInclude Include="..\..\src\rocksdb2\util\xxhash.h">
<Filter>rocksdb2\util</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\backupable\backupable_db.cc">
<Filter>rocksdb2\utilities\backupable</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\document_db.cc">
<Filter>rocksdb2\utilities\document</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\document\json_document.cc">
<Filter>rocksdb2\utilities\document</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.cc">
<Filter>rocksdb2\utilities\geodb</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\geodb\geodb_impl.h">
<Filter>rocksdb2\utilities\geodb</Filter>
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators.h">
<Filter>rocksdb2\utilities</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\put.cc">
<Filter>rocksdb2\utilities\merge_operators</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.cc">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend.h">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.cc">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\merge_operators\string_append\stringappend2.h">
<Filter>rocksdb2\utilities\merge_operators\string_append</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\merge_operators\uint64add.cc">
<Filter>rocksdb2\utilities\merge_operators</Filter>
</ClCompile>
<ClCompile Include="..\..\src\rocksdb2\utilities\redis\redis_lists.cc">
<Filter>rocksdb2\utilities\redis</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_lists.h">
<Filter>rocksdb2\utilities\redis</Filter>
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_exception.h">
<Filter>rocksdb2\utilities\redis</Filter>
</ClInclude>
<ClInclude Include="..\..\src\rocksdb2\utilities\redis\redis_list_iterator.h">
<Filter>rocksdb2\utilities\redis</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\spatialdb\spatial_db.cc">
<Filter>rocksdb2\utilities\spatialdb</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\spatialdb\utils.h">
<Filter>rocksdb2\utilities\spatialdb</Filter>
</ClInclude>
<ClCompile Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.cc">
<Filter>rocksdb2\utilities\ttl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\rocksdb2\utilities\ttl\db_ttl_impl.h">
<Filter>rocksdb2\utilities\ttl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\snappy\config\snappy-stubs-public.h">
<Filter>snappy\config</Filter>
</ClInclude>

View File

@@ -19,84 +19,110 @@
namespace ripple {
TER AddWallet::doApply ()
class AddWallet
: public Transactor
{
std::uint32_t const uTxFlags = mTxn.getFlags ();
if (uTxFlags & tfUniversalMask)
public:
AddWallet (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("AddWallet"))
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
Blob const vucPubKey = mTxn.getFieldVL (sfPublicKey);
Blob const vucSignature = mTxn.getFieldVL (sfSignature);
auto const uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey);
auto const naMasterPubKey =
RippleAddress::createAccountPublic (vucPubKey);
auto const 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, ECDSA::not_strict))
TER doApply () override
{
m_journal.trace <<
"Unauthorized: bad signature ";
return tefBAD_ADD_AUTH;
std::uint32_t const uTxFlags = mTxn.getFlags ();
if (uTxFlags & tfUniversalMask)
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
Blob const vucPubKey = mTxn.getFieldVL (sfPublicKey);
Blob const vucSignature = mTxn.getFieldVL (sfSignature);
auto const uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey);
auto const naMasterPubKey =
RippleAddress::createAccountPublic (vucPubKey);
auto const 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, ECDSA::not_strict))
{
m_journal.trace <<
"Unauthorized: bad signature ";
return tefBAD_ADD_AUTH;
}
SLE::pointer sleDst (mEngine->entryCache (
ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)));
if (sleDst)
{
m_journal.trace <<
"account already created";
return tefCREATED;
}
// Direct XRP payment.
STAmount saDstAmount = mTxn.getFieldAmount (sfAmount);
STAmount saPaid = mTxn.getTransactionFee ();
STAmount const saSrcBalance = mTxnAccount->getFieldAmount (sfBalance);
std::uint32_t const uOwnerCount = mTxnAccount->getFieldU32 (sfOwnerCount);
std::uint64_t const uReserve = mEngine->getLedger ()->getReserve (uOwnerCount);
// Make sure have enough reserve to send. Allow final spend to use reserve
// for fee.
// Note: Reserve is not scaled by fee.
if (saSrcBalance + saPaid < saDstAmount + uReserve)
{
// Vote no. However, transaction might succeed, if applied in a
// different order.
m_journal.trace <<
"Delay transaction: Insufficient funds: %s / %s (%d)" <<
saSrcBalance.getText () << " / " <<
(saDstAmount + uReserve).getText () << " with reserve = " <<
uReserve;
return tecUNFUNDED_ADD;
}
// Deduct initial balance from source account.
mTxnAccount->setFieldAmount (sfBalance, saSrcBalance - saDstAmount);
// Create the account.
sleDst = mEngine->entryCreate (ltACCOUNT_ROOT,
Ledger::getAccountRootIndex (uDstAccountID));
sleDst->setFieldAccount (sfAccount, uDstAccountID);
sleDst->setFieldU32 (sfSequence, 1);
sleDst->setFieldAmount (sfBalance, saDstAmount);
sleDst->setFieldAccount (sfRegularKey, uAuthKeyID);
return tesSUCCESS;
}
};
SLE::pointer sleDst (mEngine->entryCache (
ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)));
if (sleDst)
{
m_journal.trace <<
"account already created";
return tefCREATED;
}
// Direct XRP payment.
STAmount saDstAmount = mTxn.getFieldAmount (sfAmount);
STAmount saPaid = mTxn.getTransactionFee ();
STAmount const saSrcBalance = mTxnAccount->getFieldAmount (sfBalance);
std::uint32_t const uOwnerCount = mTxnAccount->getFieldU32 (sfOwnerCount);
std::uint64_t const uReserve = mEngine->getLedger ()->getReserve (uOwnerCount);
// Make sure have enough reserve to send. Allow final spend to use reserve
// for fee.
// Note: Reserve is not scaled by fee.
if (saSrcBalance + saPaid < saDstAmount + uReserve)
{
// Vote no. However, transaction might succeed, if applied in a
// different order.
m_journal.trace <<
"Delay transaction: Insufficient funds: %s / %s (%d)" <<
saSrcBalance.getText () << " / " <<
(saDstAmount + uReserve).getText () << " with reserve = " <<
uReserve;
return tecUNFUNDED_ADD;
}
// Deduct initial balance from source account.
mTxnAccount->setFieldAmount (sfBalance, saSrcBalance - saDstAmount);
// Create the account.
sleDst = mEngine->entryCreate (ltACCOUNT_ROOT,
Ledger::getAccountRootIndex (uDstAccountID));
sleDst->setFieldAccount (sfAccount, uDstAccountID);
sleDst->setFieldU32 (sfSequence, 1);
sleDst->setFieldAmount (sfBalance, saDstAmount);
sleDst->setFieldAccount (sfRegularKey, uAuthKeyID);
return tesSUCCESS;
TER
transact_AddWallet (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return AddWallet (txn, params, engine).apply ();
}
}

View File

@@ -1,56 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_WALLETADD_H_INCLUDED
#define RIPPLE_TX_WALLETADD_H_INCLUDED
namespace ripple {
class AddWallet
: public Transactor
{
public:
AddWallet (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("AddWallet"))
{
}
TER doApply ();
};
inline
std::unique_ptr <Transactor>
make_AddWallet (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <AddWallet> (txn, params, engine);
}
}
#endif

View File

@@ -19,54 +19,80 @@
namespace ripple {
TER CancelOffer::doApply ()
class CancelOffer
: public Transactor
{
std::uint32_t const uOfferSequence = mTxn.getFieldU32 (sfOfferSequence);
std::uint32_t const uAccountSequenceNext = mTxnAccount->getFieldU32 (sfSequence);
m_journal.debug <<
"uAccountSequenceNext=" << uAccountSequenceNext <<
" uOfferSequence=" << uOfferSequence;
std::uint32_t const uTxFlags (mTxn.getFlags ());
if (uTxFlags & tfUniversalMask)
public:
CancelOffer (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("CancelOffer"))
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
if (!uOfferSequence || uAccountSequenceNext - 1 <= uOfferSequence)
TER doApply () override
{
m_journal.trace <<
std::uint32_t const uOfferSequence = mTxn.getFieldU32 (sfOfferSequence);
std::uint32_t const uAccountSequenceNext = mTxnAccount->getFieldU32 (sfSequence);
m_journal.debug <<
"uAccountSequenceNext=" << uAccountSequenceNext <<
" uOfferSequence=" << uOfferSequence;
return temBAD_SEQUENCE;
std::uint32_t const uTxFlags (mTxn.getFlags ());
if (uTxFlags & tfUniversalMask)
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
if (!uOfferSequence || uAccountSequenceNext - 1 <= uOfferSequence)
{
m_journal.trace <<
"uAccountSequenceNext=" << uAccountSequenceNext <<
" uOfferSequence=" << uOfferSequence;
return temBAD_SEQUENCE;
}
uint256 const offerIndex (
Ledger::getOfferIndex (mTxnAccountID, uOfferSequence));
SLE::pointer sleOffer (
mEngine->entryCache (ltOFFER, offerIndex));
if (sleOffer)
{
m_journal.debug <<
"OfferCancel: uOfferSequence=" << uOfferSequence;
return mEngine->view ().offerDelete (sleOffer);
}
m_journal.warning <<
"OfferCancel: offer not found: " <<
to_string (mTxnAccountID) <<
" : " << uOfferSequence <<
" : " << to_string (offerIndex);
return tesSUCCESS;
}
};
uint256 const offerIndex (
Ledger::getOfferIndex (mTxnAccountID, uOfferSequence));
SLE::pointer sleOffer (
mEngine->entryCache (ltOFFER, offerIndex));
if (sleOffer)
{
m_journal.debug <<
"OfferCancel: uOfferSequence=" << uOfferSequence;
return mEngine->view ().offerDelete (sleOffer);
}
m_journal.warning <<
"OfferCancel: offer not found: " <<
to_string (mTxnAccountID) <<
" : " << uOfferSequence <<
" : " << to_string (offerIndex);
return tesSUCCESS;
TER
transact_CancelOffer (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return CancelOffer (txn, params, engine).apply ();
}
}

View File

@@ -1,57 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_OFFERCANCEL_H_INCLUDED
#define RIPPLE_TX_OFFERCANCEL_H_INCLUDED
namespace ripple {
class CancelOffer
: public Transactor
{
public:
CancelOffer (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("CancelOffer"))
{
}
TER doApply () override;
};
inline
std::unique_ptr <Transactor>
make_CancelOffer (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <CancelOffer> (txn, params, engine);
}
}
#endif

View File

@@ -19,134 +19,168 @@
namespace ripple {
TER Change::doApply ()
class Change
: public Transactor
{
if (mTxn.getTxnType () == ttAMENDMENT)
return applyAmendment ();
if (mTxn.getTxnType () == ttFEE)
return applyFee ();
return temUNKNOWN;
}
TER Change::checkSig ()
{
if (mTxn.getFieldAccount160 (sfAccount).isNonZero ())
public:
Change (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("Change"))
{
m_journal.warning << "Bad source account";
return temBAD_SRC_ACCOUNT;
}
if (!mTxn.getSigningPubKey ().empty () || !mTxn.getSignature ().empty ())
TER doApply () override
{
m_journal.warning << "Bad signature";
return temBAD_SIGNATURE;
if (mTxn.getTxnType () == ttAMENDMENT)
return applyAmendment ();
if (mTxn.getTxnType () == ttFEE)
return applyFee ();
return temUNKNOWN;
}
return tesSUCCESS;
}
TER Change::checkSeq ()
{
if ((mTxn.getSequence () != 0) || mTxn.isFieldPresent (sfPreviousTxnID))
TER checkSig () override
{
m_journal.warning << "Bad sequence";
return temBAD_SEQUENCE;
if (mTxn.getFieldAccount160 (sfAccount).isNonZero ())
{
m_journal.warning << "Bad source account";
return temBAD_SRC_ACCOUNT;
}
if (!mTxn.getSigningPubKey ().empty () || !mTxn.getSignature ().empty ())
{
m_journal.warning << "Bad signature";
return temBAD_SIGNATURE;
}
return tesSUCCESS;
}
return tesSUCCESS;
}
TER Change::payFee ()
{
if (mTxn.getTransactionFee () != STAmount ())
TER checkSeq () override
{
m_journal.warning << "Non-zero fee";
return temBAD_FEE;
if ((mTxn.getSequence () != 0) || mTxn.isFieldPresent (sfPreviousTxnID))
{
m_journal.warning << "Bad sequence";
return temBAD_SEQUENCE;
}
return tesSUCCESS;
}
return tesSUCCESS;
}
TER Change::preCheck ()
{
mTxnAccountID = mTxn.getSourceAccount ().getAccountID ();
if (mTxnAccountID.isNonZero ())
TER payFee () override
{
m_journal.warning << "Bad source id";
if (mTxn.getTransactionFee () != STAmount ())
{
m_journal.warning << "Non-zero fee";
return temBAD_FEE;
}
return temBAD_SRC_ACCOUNT;
return tesSUCCESS;
}
if (mParams & tapOPEN_LEDGER)
TER preCheck () override
{
m_journal.warning << "Change transaction against open ledger";
return temINVALID;
mTxnAccountID = mTxn.getSourceAccount ().getAccountID ();
if (mTxnAccountID.isNonZero ())
{
m_journal.warning << "Bad source id";
return temBAD_SRC_ACCOUNT;
}
if (mParams & tapOPEN_LEDGER)
{
m_journal.warning << "Change transaction against open ledger";
return temINVALID;
}
return tesSUCCESS;
}
return tesSUCCESS;
}
TER Change::applyAmendment ()
{
uint256 amendment (mTxn.getFieldH256 (sfAmendment));
SLE::pointer amendmentObject (mEngine->entryCache (
ltAMENDMENTS, Ledger::getLedgerAmendmentIndex ()));
if (!amendmentObject)
private:
TER applyAmendment ()
{
amendmentObject = mEngine->entryCreate(
ltAMENDMENTS, Ledger::getLedgerAmendmentIndex());
uint256 amendment (mTxn.getFieldH256 (sfAmendment));
SLE::pointer amendmentObject (mEngine->entryCache (
ltAMENDMENTS, Ledger::getLedgerAmendmentIndex ()));
if (!amendmentObject)
{
amendmentObject = mEngine->entryCreate(
ltAMENDMENTS, Ledger::getLedgerAmendmentIndex());
}
STVector256 amendments (amendmentObject->getFieldV256 (sfAmendments));
if (amendments.hasValue (amendment))
return tefALREADY;
amendments.addValue (amendment);
amendmentObject->setFieldV256 (sfAmendments, amendments);
mEngine->entryModify (amendmentObject);
getApp().getAmendmentTable ().enable (amendment);
if (!getApp().getAmendmentTable ().isSupported (amendment))
getApp().getOPs ().setAmendmentBlocked ();
return tesSUCCESS;
}
STVector256 amendments (amendmentObject->getFieldV256 (sfAmendments));
TER applyFee ()
{
if (amendments.hasValue (amendment))
return tefALREADY;
amendments.addValue (amendment);
amendmentObject->setFieldV256 (sfAmendments, amendments);
mEngine->entryModify (amendmentObject);
getApp().getAmendmentTable ().enable (amendment);
if (!getApp().getAmendmentTable ().isSupported (amendment))
getApp().getOPs ().setAmendmentBlocked ();
return tesSUCCESS;
}
TER Change::applyFee ()
{
SLE::pointer feeObject = mEngine->entryCache (
ltFEE_SETTINGS, Ledger::getLedgerFeeIndex ());
if (!feeObject)
feeObject = mEngine->entryCreate (
SLE::pointer feeObject = mEngine->entryCache (
ltFEE_SETTINGS, Ledger::getLedgerFeeIndex ());
m_journal.trace <<
"Previous fee object: " << feeObject->getJson (0);
if (!feeObject)
feeObject = mEngine->entryCreate (
ltFEE_SETTINGS, Ledger::getLedgerFeeIndex ());
feeObject->setFieldU64 (
sfBaseFee, mTxn.getFieldU64 (sfBaseFee));
feeObject->setFieldU32 (
sfReferenceFeeUnits, mTxn.getFieldU32 (sfReferenceFeeUnits));
feeObject->setFieldU32 (
sfReserveBase, mTxn.getFieldU32 (sfReserveBase));
feeObject->setFieldU32 (
sfReserveIncrement, mTxn.getFieldU32 (sfReserveIncrement));
m_journal.trace <<
"Previous fee object: " << feeObject->getJson (0);
mEngine->entryModify (feeObject);
feeObject->setFieldU64 (
sfBaseFee, mTxn.getFieldU64 (sfBaseFee));
feeObject->setFieldU32 (
sfReferenceFeeUnits, mTxn.getFieldU32 (sfReferenceFeeUnits));
feeObject->setFieldU32 (
sfReserveBase, mTxn.getFieldU32 (sfReserveBase));
feeObject->setFieldU32 (
sfReserveIncrement, mTxn.getFieldU32 (sfReserveIncrement));
m_journal.trace <<
"New fee object: " << feeObject->getJson (0);
m_journal.warning << "Fees have been changed";
return tesSUCCESS;
mEngine->entryModify (feeObject);
m_journal.trace <<
"New fee object: " << feeObject->getJson (0);
m_journal.warning << "Fees have been changed";
return tesSUCCESS;
}
// VFALCO TODO Can this be removed?
bool mustHaveValidAccount () override
{
return false;
}
};
TER
transact_Change (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return Change (txn, params, engine).apply ();
}
}

View File

@@ -1,71 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_CHANGE_H_INCLUDED
#define RIPPLE_TX_CHANGE_H_INCLUDED
namespace ripple {
class Change
: public Transactor
{
public:
Change (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("Change"))
{
}
TER doApply () override;
TER checkSig () override;
TER checkSeq () override;
TER payFee () override;
TER preCheck () override;
private:
TER applyAmendment ();
TER applyFee ();
// VFALCO TODO Can this be removed?
bool mustHaveValidAccount () override
{
return false;
}
};
inline
std::unique_ptr <Transactor>
make_Change (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <Change> (txn, params, engine);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,67 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_OFFERCREATE_H_INCLUDED
#define RIPPLE_TX_OFFERCREATE_H_INCLUDED
#include <ripple/module/app/book/Amounts.h>
#include <ripple/module/app/book/Types.h>
#include <beast/cxx14/memory.h>
namespace ripple {
class CreateOffer
: public Transactor
{
protected:
/** Determine if we are authorized to hold the asset we want to get */
TER checkAcceptAsset(IssueRef asset) const;
/** Fill offer as much as possible by consuming offers already on the books.
We adjusts account balances and charges fees on top to taker.
@param taker_amount.in How much the taker offers
@param taker_amount.out How much the taker wants
@return result.first crossing operation success/failure indicator.
result.second amount of offer left unfilled - only meaningful
if result.first is tesSUCCESS.
*/
virtual std::pair<TER, core::Amounts> crossOffers (
core::LedgerView& view,
core::Amounts const& taker_amount) = 0;
public:
CreateOffer (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine);
TER doApply () override;
};
std::unique_ptr <Transactor> make_CreateOffer (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine);
}
#endif

View File

@@ -25,7 +25,7 @@
namespace ripple {
std::pair<TER, core::Amounts>
CreateOfferBridged::crossOffers (
CreateOffer::crossOffersBridged (
core::LedgerView& view,
core::Amounts const& taker_amount)
{

View File

@@ -1,51 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_BRIDGE_OFFERCREATE_H_INCLUDED
#define RIPPLE_TX_BRIDGE_OFFERCREATE_H_INCLUDED
#include <ripple/module/app/book/Amounts.h>
namespace ripple {
class CreateOfferBridged
: public CreateOffer
{
public:
CreateOfferBridged (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: CreateOffer (
txn,
params,
engine)
{
}
private:
std::pair<TER, core::Amounts> crossOffers (
core::LedgerView& view,
core::Amounts const& taker_amount) override;
};
}
#endif

View File

@@ -23,19 +23,8 @@
namespace ripple {
/** Fill offer as much as possible by consuming offers already on the books.
We adjusts account balances and charges fees on top to taker.
@param taker_amount.in How much the taker offers
@param taker_amount.out How much the taker wants
@param taker_flow.in What the taker actually paid, not including fees.
@param taker_flow.out What the taker actually got, not including fees.
@return tesSUCCESS, terNO_ACCOUNT, telFAILED_PROCESSING, or
tecFAILED_PROCESSING
*/
std::pair<TER, core::Amounts>
CreateOfferDirect::crossOffers (
CreateOffer::crossOffersDirect (
core::LedgerView& view,
core::Amounts const& taker_amount)
{

View File

@@ -1,51 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_DIRECT_OFFERCREATE_H_INCLUDED
#define RIPPLE_TX_DIRECT_OFFERCREATE_H_INCLUDED
#include <ripple/module/app/book/Amounts.h>
namespace ripple {
class CreateOfferDirect
: public CreateOffer
{
public:
CreateOfferDirect (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: CreateOffer (
txn,
params,
engine)
{
}
private:
std::pair<TER, core::Amounts> crossOffers (
core::LedgerView& view,
core::Amounts const& taker_amount) override;
};
}
#endif

View File

@@ -21,329 +21,362 @@ namespace ripple {
// See https://ripple.com/wiki/Transaction_Format#Payment_.280.29
TER Payment::doApply ()
class Payment
: public Transactor
{
// Ripple if source or destination is non-native or if there are paths.
std::uint32_t const uTxFlags = mTxn.getFlags ();
bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
bool const limitQuality = uTxFlags & tfLimitQuality;
bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
bool const bPaths = mTxn.isFieldPresent (sfPaths);
bool const bMax = mTxn.isFieldPresent (sfSendMax);
Account const uDstAccountID (mTxn.getFieldAccount160 (sfDestination));
STAmount const saDstAmount (mTxn.getFieldAmount (sfAmount));
STAmount maxSourceAmount;
if (bMax)
maxSourceAmount = mTxn.getFieldAmount (sfSendMax);
else if (saDstAmount.isNative ())
maxSourceAmount = saDstAmount;
else
maxSourceAmount = STAmount (
{saDstAmount.getCurrency (), mTxnAccountID},
saDstAmount.getMantissa (), saDstAmount.getExponent (),
saDstAmount < zero);
auto const& uSrcCurrency = maxSourceAmount.getCurrency ();
auto const& uDstCurrency = saDstAmount.getCurrency ();
/* The largest number of paths we allow */
static std::size_t const MaxPathSize = 6;
// isZero() is XRP. FIX!
bool const bXRPDirect = uSrcCurrency.isZero () && uDstCurrency.isZero ();
/* The longest path we allow */
static std::size_t const MaxPathLength = 8;
m_journal.trace <<
"maxSourceAmount=" << maxSourceAmount.getFullText () <<
" saDstAmount=" << saDstAmount.getFullText ();
if (!saDstAmount.isLegalNet () || !maxSourceAmount.isLegalNet ())
return temBAD_AMOUNT;
if (uTxFlags & tfPaymentMask)
public:
Payment (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("Payment"))
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
else if (!uDstAccountID)
{
m_journal.trace <<
"Malformed transaction: Payment destination account not specified.";
return temDST_NEEDED;
}
else if (bMax && maxSourceAmount <= zero)
{
m_journal.trace <<
"Malformed transaction: bad max amount: " << maxSourceAmount.getFullText ();
return temBAD_AMOUNT;
}
else if (saDstAmount <= zero)
{
m_journal.trace <<
"Malformed transaction: bad dst amount: " << saDstAmount.getFullText ();
return temBAD_AMOUNT;
}
else if (badCurrency() == uSrcCurrency || badCurrency() == uDstCurrency)
{
m_journal.trace <<
"Malformed transaction: Bad currency.";
return temBAD_CURRENCY;
}
else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
{
// You're signing yourself a payment.
// If bPaths is true, you might be trying some arbitrage.
m_journal.trace <<
"Malformed transaction: Redundant transaction:" <<
" src=" << to_string (mTxnAccountID) <<
" dst=" << to_string (uDstAccountID) <<
" src_cur=" << to_string (uSrcCurrency) <<
" dst_cur=" << to_string (uDstCurrency);
return temREDUNDANT;
}
else if (bMax && maxSourceAmount == saDstAmount &&
maxSourceAmount.getCurrency () == saDstAmount.getCurrency ())
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: Redundant SendMax.";
return temREDUNDANT_SEND_MAX;
}
else if (bXRPDirect && bMax)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: SendMax specified for XRP to XRP.";
return temBAD_SEND_XRP_MAX;
}
else if (bXRPDirect && bPaths)
{
// XRP is sent without paths.
m_journal.trace <<
"Malformed transaction: Paths specified for XRP to XRP.";
return temBAD_SEND_XRP_PATHS;
}
else if (bXRPDirect && partialPaymentAllowed)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: Partial payment specified for XRP to XRP.";
return temBAD_SEND_XRP_PARTIAL;
}
else if (bXRPDirect && limitQuality)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: Limit quality specified for XRP to XRP.";
return temBAD_SEND_XRP_LIMIT;
}
else if (bXRPDirect && !defaultPathsAllowed)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: No ripple direct specified for XRP to XRP.";
return temBAD_SEND_XRP_NO_DIRECT;
}
//
// Open a ledger for editing.
auto const index = Ledger::getAccountRootIndex (uDstAccountID);
SLE::pointer sleDst (mEngine->entryCache (ltACCOUNT_ROOT, index));
if (!sleDst)
TER doApply () override
{
// Destination account does not exist.
if (!saDstAmount.isNative ())
// Ripple if source or destination is non-native or if there are paths.
std::uint32_t const uTxFlags = mTxn.getFlags ();
bool const partialPaymentAllowed = uTxFlags & tfPartialPayment;
bool const limitQuality = uTxFlags & tfLimitQuality;
bool const defaultPathsAllowed = !(uTxFlags & tfNoRippleDirect);
bool const bPaths = mTxn.isFieldPresent (sfPaths);
bool const bMax = mTxn.isFieldPresent (sfSendMax);
Account const uDstAccountID (mTxn.getFieldAccount160 (sfDestination));
STAmount const saDstAmount (mTxn.getFieldAmount (sfAmount));
STAmount maxSourceAmount;
if (bMax)
maxSourceAmount = mTxn.getFieldAmount (sfSendMax);
else if (saDstAmount.isNative ())
maxSourceAmount = saDstAmount;
else
maxSourceAmount = STAmount (
{saDstAmount.getCurrency (), mTxnAccountID},
saDstAmount.getMantissa (), saDstAmount.getExponent (),
saDstAmount < zero);
auto const& uSrcCurrency = maxSourceAmount.getCurrency ();
auto const& uDstCurrency = saDstAmount.getCurrency ();
// isZero() is XRP. FIX!
bool const bXRPDirect = uSrcCurrency.isZero () && uDstCurrency.isZero ();
m_journal.trace <<
"maxSourceAmount=" << maxSourceAmount.getFullText () <<
" saDstAmount=" << saDstAmount.getFullText ();
if (!saDstAmount.isLegalNet () || !maxSourceAmount.isLegalNet ())
return temBAD_AMOUNT;
if (uTxFlags & tfPaymentMask)
{
m_journal.trace <<
"Delay transaction: Destination account does not exist.";
"Malformed transaction: Invalid flags set.";
// Another transaction could create the account and then this
// transaction would succeed.
return tecNO_DST;
return temINVALID_FLAG;
}
else if (mParams & tapOPEN_LEDGER && partialPaymentAllowed)
{
// You cannot fund an account with a partial payment.
// Make retry work smaller, by rejecting this.
m_journal.trace <<
"Delay transaction: Partial payment not allowed to create account.";
// Another transaction could create the account and then this
// transaction would succeed.
return telNO_DST_PARTIAL;
}
else if (saDstAmount.getNValue () < mEngine->getLedger ()->getReserve (0))
{
// getReserve() is the minimum amount that an account can have.
// Reserve is not scaled by load.
m_journal.trace <<
"Delay transaction: Destination account does not exist. " <<
"Insufficent payment to create account.";
// TODO: dedupe
// Another transaction could create the account and then this
// transaction would succeed.
return tecNO_DST_INSUF_XRP;
}
// Create the account.
auto const newIndex = Ledger::getAccountRootIndex (uDstAccountID);
sleDst = mEngine->entryCreate (ltACCOUNT_ROOT, newIndex);
sleDst->setFieldAccount (sfAccount, uDstAccountID);
sleDst->setFieldU32 (sfSequence, 1);
}
else if ((sleDst->getFlags () & lsfRequireDestTag) &&
!mTxn.isFieldPresent (sfDestinationTag))
{
// The tag is basically account-specific information we don't
// understand, but we can require someone to fill it in.
// We didn't make this test for a newly-formed account because there's
// no way for this field to be set.
m_journal.trace << "Malformed transaction: DestinationTag required.";
return tefDST_TAG_NEEDED;
}
else
{
// Tell the engine that we are intending to change the the destination
// account. The source account gets always charged a fee so it's always
// marked as modified.
mEngine->entryModify (sleDst);
}
TER terResult;
bool const bRipple = bPaths || bMax || !saDstAmount.isNative ();
// XXX Should bMax be sufficient to imply ripple?
if (bRipple)
{
// Ripple payment with at least one intermediate step and uses
// transitive balances.
// Copy paths into an editable class.
STPathSet spsPaths = mTxn.getFieldPathSet (sfPaths);
try
{
path::RippleCalc::Input rcInput;
rcInput.partialPaymentAllowed = partialPaymentAllowed;
rcInput.defaultPathsAllowed = defaultPathsAllowed;
rcInput.limitQuality = limitQuality;
rcInput.deleteUnfundedOffers = true;
rcInput.isLedgerOpen = static_cast<bool>(mParams & tapOPEN_LEDGER);
bool pathTooBig = spsPaths.size () > MaxPathSize;
for (auto const& path : spsPaths)
if (path.size () > MaxPathLength)
pathTooBig = true;
if (rcInput.isLedgerOpen && pathTooBig)
{
terResult = telBAD_PATH_COUNT; // Too many paths for proposed ledger.
}
else
{
auto rc = path::RippleCalc::rippleCalculate (
mEngine->view (),
maxSourceAmount,
saDstAmount,
uDstAccountID,
mTxnAccountID,
spsPaths,
&rcInput);
// TODO: is this right? If the amount is the correct amount, was
// the delivered amount previously set?
if (rc.result () == tesSUCCESS && rc.actualAmountOut != saDstAmount)
mEngine->view ().setDeliveredAmount (rc.actualAmountOut);
terResult = rc.result ();
}
// TODO(tom): what's going on here?
if (isTerRetry (terResult))
terResult = tecPATH_DRY;
}
catch (std::exception const& e)
else if (!uDstAccountID)
{
m_journal.trace <<
"Caught throw: " << e.what ();
"Malformed transaction: Payment destination account not specified.";
terResult = tefEXCEPTION;
return temDST_NEEDED;
}
}
else
{
// Direct XRP payment.
else if (bMax && maxSourceAmount <= zero)
{
m_journal.trace <<
"Malformed transaction: bad max amount: " << maxSourceAmount.getFullText ();
// uOwnerCount is the number of entries in this legder for this account
// that require a reserve.
return temBAD_AMOUNT;
}
else if (saDstAmount <= zero)
{
m_journal.trace <<
"Malformed transaction: bad dst amount: " << saDstAmount.getFullText ();
std::uint32_t const uOwnerCount (mTxnAccount->getFieldU32 (sfOwnerCount));
return temBAD_AMOUNT;
}
else if (badCurrency() == uSrcCurrency || badCurrency() == uDstCurrency)
{
m_journal.trace <<
"Malformed transaction: Bad currency.";
// This is the total reserve in drops.
// TODO(tom): there should be a class for this.
std::uint64_t const uReserve (mEngine->getLedger ()->getReserve (uOwnerCount));
return temBAD_CURRENCY;
}
else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths)
{
// You're signing yourself a payment.
// If bPaths is true, you might be trying some arbitrage.
m_journal.trace <<
"Malformed transaction: Redundant transaction:" <<
" src=" << to_string (mTxnAccountID) <<
" dst=" << to_string (uDstAccountID) <<
" src_cur=" << to_string (uSrcCurrency) <<
" dst_cur=" << to_string (uDstCurrency);
return temREDUNDANT;
}
else if (bMax && maxSourceAmount == saDstAmount &&
maxSourceAmount.getCurrency () == saDstAmount.getCurrency ())
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: Redundant SendMax.";
return temREDUNDANT_SEND_MAX;
}
else if (bXRPDirect && bMax)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: SendMax specified for XRP to XRP.";
return temBAD_SEND_XRP_MAX;
}
else if (bXRPDirect && bPaths)
{
// XRP is sent without paths.
m_journal.trace <<
"Malformed transaction: Paths specified for XRP to XRP.";
return temBAD_SEND_XRP_PATHS;
}
else if (bXRPDirect && partialPaymentAllowed)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: Partial payment specified for XRP to XRP.";
return temBAD_SEND_XRP_PARTIAL;
}
else if (bXRPDirect && limitQuality)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: Limit quality specified for XRP to XRP.";
return temBAD_SEND_XRP_LIMIT;
}
else if (bXRPDirect && !defaultPathsAllowed)
{
// Consistent but redundant transaction.
m_journal.trace <<
"Malformed transaction: No ripple direct specified for XRP to XRP.";
return temBAD_SEND_XRP_NO_DIRECT;
}
// mPriorBalance is the balance on the sending account BEFORE the fees were charged.
//
// Make sure have enough reserve to send. Allow final spend to use
// reserve for fee.
auto const mmm = std::max(uReserve, mTxn.getTransactionFee ().getNValue ());
if (mPriorBalance < saDstAmount + mmm)
{
// Vote no.
// However, transaction might succeed, if applied in a different order.
m_journal.trace << "Delay transaction: Insufficient funds: " <<
" " << mPriorBalance.getText () <<
" / " << (saDstAmount + uReserve).getText () <<
" (" << uReserve << ")";
// Open a ledger for editing.
auto const index = Ledger::getAccountRootIndex (uDstAccountID);
SLE::pointer sleDst (mEngine->entryCache (ltACCOUNT_ROOT, index));
terResult = tecUNFUNDED_PAYMENT;
if (!sleDst)
{
// Destination account does not exist.
if (!saDstAmount.isNative ())
{
m_journal.trace <<
"Delay transaction: Destination account does not exist.";
// Another transaction could create the account and then this
// transaction would succeed.
return tecNO_DST;
}
else if (mParams & tapOPEN_LEDGER && partialPaymentAllowed)
{
// You cannot fund an account with a partial payment.
// Make retry work smaller, by rejecting this.
m_journal.trace <<
"Delay transaction: Partial payment not allowed to create account.";
// Another transaction could create the account and then this
// transaction would succeed.
return telNO_DST_PARTIAL;
}
else if (saDstAmount.getNValue () < mEngine->getLedger ()->getReserve (0))
{
// getReserve() is the minimum amount that an account can have.
// Reserve is not scaled by load.
m_journal.trace <<
"Delay transaction: Destination account does not exist. " <<
"Insufficent payment to create account.";
// TODO: dedupe
// Another transaction could create the account and then this
// transaction would succeed.
return tecNO_DST_INSUF_XRP;
}
// Create the account.
auto const newIndex = Ledger::getAccountRootIndex (uDstAccountID);
sleDst = mEngine->entryCreate (ltACCOUNT_ROOT, newIndex);
sleDst->setFieldAccount (sfAccount, uDstAccountID);
sleDst->setFieldU32 (sfSequence, 1);
}
else if ((sleDst->getFlags () & lsfRequireDestTag) &&
!mTxn.isFieldPresent (sfDestinationTag))
{
// The tag is basically account-specific information we don't
// understand, but we can require someone to fill it in.
// We didn't make this test for a newly-formed account because there's
// no way for this field to be set.
m_journal.trace << "Malformed transaction: DestinationTag required.";
return tefDST_TAG_NEEDED;
}
else
{
// The source account does have enough money, so do the arithmetic
// for the transfer and make the ledger change.
mTxnAccount->setFieldAmount (sfBalance, mSourceBalance - saDstAmount);
sleDst->setFieldAmount (sfBalance, sleDst->getFieldAmount (sfBalance) + saDstAmount);
// Re-arm the password change fee if we can and need to.
if ((sleDst->getFlags () & lsfPasswordSpent))
sleDst->clearFlag (lsfPasswordSpent);
terResult = tesSUCCESS;
// Tell the engine that we are intending to change the the destination
// account. The source account gets always charged a fee so it's always
// marked as modified.
mEngine->entryModify (sleDst);
}
}
std::string strToken;
std::string strHuman;
TER terResult;
if (transResultInfo (terResult, strToken, strHuman))
{
m_journal.trace <<
strToken << ": " << strHuman;
}
else
{
assert (false);
}
bool const bRipple = bPaths || bMax || !saDstAmount.isNative ();
// XXX Should bMax be sufficient to imply ripple?
return terResult;
if (bRipple)
{
// Ripple payment with at least one intermediate step and uses
// transitive balances.
// Copy paths into an editable class.
STPathSet spsPaths = mTxn.getFieldPathSet (sfPaths);
try
{
path::RippleCalc::Input rcInput;
rcInput.partialPaymentAllowed = partialPaymentAllowed;
rcInput.defaultPathsAllowed = defaultPathsAllowed;
rcInput.limitQuality = limitQuality;
rcInput.deleteUnfundedOffers = true;
rcInput.isLedgerOpen = static_cast<bool>(mParams & tapOPEN_LEDGER);
bool pathTooBig = spsPaths.size () > MaxPathSize;
for (auto const& path : spsPaths)
if (path.size () > MaxPathLength)
pathTooBig = true;
if (rcInput.isLedgerOpen && pathTooBig)
{
terResult = telBAD_PATH_COUNT; // Too many paths for proposed ledger.
}
else
{
auto rc = path::RippleCalc::rippleCalculate (
mEngine->view (),
maxSourceAmount,
saDstAmount,
uDstAccountID,
mTxnAccountID,
spsPaths,
&rcInput);
// TODO: is this right? If the amount is the correct amount, was
// the delivered amount previously set?
if (rc.result () == tesSUCCESS && rc.actualAmountOut != saDstAmount)
mEngine->view ().setDeliveredAmount (rc.actualAmountOut);
terResult = rc.result ();
}
// TODO(tom): what's going on here?
if (isTerRetry (terResult))
terResult = tecPATH_DRY;
}
catch (std::exception const& e)
{
m_journal.trace <<
"Caught throw: " << e.what ();
terResult = tefEXCEPTION;
}
}
else
{
// Direct XRP payment.
// uOwnerCount is the number of entries in this legder for this account
// that require a reserve.
std::uint32_t const uOwnerCount (mTxnAccount->getFieldU32 (sfOwnerCount));
// This is the total reserve in drops.
// TODO(tom): there should be a class for this.
std::uint64_t const uReserve (mEngine->getLedger ()->getReserve (uOwnerCount));
// mPriorBalance is the balance on the sending account BEFORE the fees were charged.
//
// Make sure have enough reserve to send. Allow final spend to use
// reserve for fee.
auto const mmm = std::max(uReserve, mTxn.getTransactionFee ().getNValue ());
if (mPriorBalance < saDstAmount + mmm)
{
// Vote no.
// However, transaction might succeed, if applied in a different order.
m_journal.trace << "Delay transaction: Insufficient funds: " <<
" " << mPriorBalance.getText () <<
" / " << (saDstAmount + uReserve).getText () <<
" (" << uReserve << ")";
terResult = tecUNFUNDED_PAYMENT;
}
else
{
// The source account does have enough money, so do the arithmetic
// for the transfer and make the ledger change.
mTxnAccount->setFieldAmount (sfBalance, mSourceBalance - saDstAmount);
sleDst->setFieldAmount (sfBalance, sleDst->getFieldAmount (sfBalance) + saDstAmount);
// Re-arm the password change fee if we can and need to.
if ((sleDst->getFlags () & lsfPasswordSpent))
sleDst->clearFlag (lsfPasswordSpent);
terResult = tesSUCCESS;
}
}
std::string strToken;
std::string strHuman;
if (transResultInfo (terResult, strToken, strHuman))
{
m_journal.trace <<
strToken << ": " << strHuman;
}
else
{
assert (false);
}
return terResult;
}
};
TER
transact_Payment (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return Payment(txn, params, engine).apply ();
}
} // ripple

View File

@@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_PAYMENT_H_INCLUDED
#define RIPPLE_TX_PAYMENT_H_INCLUDED
namespace ripple {
class Payment
: public Transactor
{
/* The largest number of paths we allow */
static std::size_t const MaxPathSize = 6;
/* The longest path we allow */
static std::size_t const MaxPathLength = 8;
public:
Payment (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("Payment"))
{
}
TER doApply ();
};
inline
std::unique_ptr <Transactor>
make_Payment (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <Payment> (txn, params, engine);
}
}
#endif

View File

@@ -19,298 +19,325 @@
namespace ripple {
TER SetAccount::doApply ()
class SetAccount
: public Transactor
{
std::uint32_t const uTxFlags = mTxn.getFlags ();
std::uint32_t const uFlagsIn = mTxnAccount->getFieldU32 (sfFlags);
std::uint32_t uFlagsOut = uFlagsIn;
std::uint32_t const uSetFlag = mTxn.getFieldU32 (sfSetFlag);
std::uint32_t const uClearFlag = mTxn.getFieldU32 (sfClearFlag);
if ((uSetFlag != 0) && (uSetFlag == uClearFlag))
public:
SetAccount (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("SetAccount"))
{
m_journal.trace << "Malformed transaction: Set and clear same flag";
return temINVALID_FLAG;
}
// legacy AccountSet flags
bool bSetRequireDest = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest);
bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest);
bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth);
bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth);
bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP);
bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP);
if (uTxFlags & tfAccountSetMask)
TER doApply () override
{
m_journal.trace << "Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
std::uint32_t const uTxFlags = mTxn.getFlags ();
//
// RequireAuth
//
std::uint32_t const uFlagsIn = mTxnAccount->getFieldU32 (sfFlags);
std::uint32_t uFlagsOut = uFlagsIn;
if (bSetRequireAuth && bClearRequireAuth)
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
std::uint32_t const uSetFlag = mTxn.getFieldU32 (sfSetFlag);
std::uint32_t const uClearFlag = mTxn.getFieldU32 (sfClearFlag);
if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth))
{
if (!mEngine->view().dirIsEmpty (Ledger::getOwnerDirIndex (mTxnAccountID)))
if ((uSetFlag != 0) && (uSetFlag == uClearFlag))
{
m_journal.trace << "Retry: Owner directory not empty.";
return (mParams & tapRETRY) ? terOWNERS : tecOWNERS;
m_journal.trace << "Malformed transaction: Set and clear same flag";
return temINVALID_FLAG;
}
m_journal.trace << "Set RequireAuth.";
uFlagsOut |= lsfRequireAuth;
}
// legacy AccountSet flags
bool bSetRequireDest = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest);
bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest);
bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth);
bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth);
bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP);
bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP);
if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth))
{
m_journal.trace << "Clear RequireAuth.";
uFlagsOut &= ~lsfRequireAuth;
}
//
// RequireDestTag
//
if (bSetRequireDest && bClearRequireDest)
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag))
{
m_journal.trace << "Set lsfRequireDestTag.";
uFlagsOut |= lsfRequireDestTag;
}
if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag))
{
m_journal.trace << "Clear lsfRequireDestTag.";
uFlagsOut &= ~lsfRequireDestTag;
}
//
// DisallowXRP
//
if (bSetDisallowXRP && bClearDisallowXRP)
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP))
{
m_journal.trace << "Set lsfDisallowXRP.";
uFlagsOut |= lsfDisallowXRP;
}
if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP))
{
m_journal.trace << "Clear lsfDisallowXRP.";
uFlagsOut &= ~lsfDisallowXRP;
}
//
// DisableMaster
//
if ((uSetFlag == asfDisableMaster) && (uClearFlag == asfDisableMaster))
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster))
{
if (!mTxnAccount->isFieldPresent (sfRegularKey))
return tecNO_REGULAR_KEY;
m_journal.trace << "Set lsfDisableMaster.";
uFlagsOut |= lsfDisableMaster;
}
if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster))
{
m_journal.trace << "Clear lsfDisableMaster.";
uFlagsOut &= ~lsfDisableMaster;
}
if ((uSetFlag == asfNoFreeze) && (uClearFlag != asfNoFreeze))
{
m_journal.trace << "Set NoFreeze flag";
uFlagsOut |= lsfNoFreeze;
}
// Anyone may set global freeze
if ((uSetFlag == asfGlobalFreeze) && (uClearFlag != asfGlobalFreeze))
{
m_journal.trace << "Set GlobalFreeze flag";
uFlagsOut |= lsfGlobalFreeze;
}
// If you have set NoFreeze, you may not clear GlobalFreeze
// This prevents those who have set NoFreeze from using
// GlobalFreeze strategically.
if ((uSetFlag != asfGlobalFreeze) && (uClearFlag == asfGlobalFreeze) &&
((uFlagsOut & lsfNoFreeze) == 0))
{
m_journal.trace << "Clear GlobalFreeze flag";
uFlagsOut &= ~lsfGlobalFreeze;
}
//
// Track transaction IDs signed by this account in its root
//
if ((uSetFlag == asfAccountTxnID) && (uClearFlag != asfAccountTxnID) && !mTxnAccount->isFieldPresent (sfAccountTxnID))
{
m_journal.trace << "Set AccountTxnID";
mTxnAccount->makeFieldPresent (sfAccountTxnID);
}
if ((uClearFlag == asfAccountTxnID) && (uSetFlag != asfAccountTxnID) && mTxnAccount->isFieldPresent (sfAccountTxnID))
{
m_journal.trace << "Clear AccountTxnID";
mTxnAccount->makeFieldAbsent (sfAccountTxnID);
}
//
// EmailHash
//
if (mTxn.isFieldPresent (sfEmailHash))
{
uint128 uHash = mTxn.getFieldH128 (sfEmailHash);
if (!uHash)
if (uTxFlags & tfAccountSetMask)
{
m_journal.trace << "unset email hash";
mTxnAccount->makeFieldAbsent (sfEmailHash);
m_journal.trace << "Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
else
//
// RequireAuth
//
if (bSetRequireAuth && bClearRequireAuth)
{
m_journal.trace << "set email hash";
mTxnAccount->setFieldH128 (sfEmailHash, uHash);
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth))
{
if (!mEngine->view().dirIsEmpty (Ledger::getOwnerDirIndex (mTxnAccountID)))
{
m_journal.trace << "Retry: Owner directory not empty.";
return (mParams & tapRETRY) ? terOWNERS : tecOWNERS;
}
m_journal.trace << "Set RequireAuth.";
uFlagsOut |= lsfRequireAuth;
}
if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth))
{
m_journal.trace << "Clear RequireAuth.";
uFlagsOut &= ~lsfRequireAuth;
}
//
// RequireDestTag
//
if (bSetRequireDest && bClearRequireDest)
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag))
{
m_journal.trace << "Set lsfRequireDestTag.";
uFlagsOut |= lsfRequireDestTag;
}
if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag))
{
m_journal.trace << "Clear lsfRequireDestTag.";
uFlagsOut &= ~lsfRequireDestTag;
}
//
// DisallowXRP
//
if (bSetDisallowXRP && bClearDisallowXRP)
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP))
{
m_journal.trace << "Set lsfDisallowXRP.";
uFlagsOut |= lsfDisallowXRP;
}
if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP))
{
m_journal.trace << "Clear lsfDisallowXRP.";
uFlagsOut &= ~lsfDisallowXRP;
}
//
// DisableMaster
//
if ((uSetFlag == asfDisableMaster) && (uClearFlag == asfDisableMaster))
{
m_journal.trace << "Malformed transaction: Contradictory flags set.";
return temINVALID_FLAG;
}
if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster))
{
if (!mTxnAccount->isFieldPresent (sfRegularKey))
return tecNO_REGULAR_KEY;
m_journal.trace << "Set lsfDisableMaster.";
uFlagsOut |= lsfDisableMaster;
}
if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster))
{
m_journal.trace << "Clear lsfDisableMaster.";
uFlagsOut &= ~lsfDisableMaster;
}
if ((uSetFlag == asfNoFreeze) && (uClearFlag != asfNoFreeze))
{
m_journal.trace << "Set NoFreeze flag";
uFlagsOut |= lsfNoFreeze;
}
// Anyone may set global freeze
if ((uSetFlag == asfGlobalFreeze) && (uClearFlag != asfGlobalFreeze))
{
m_journal.trace << "Set GlobalFreeze flag";
uFlagsOut |= lsfGlobalFreeze;
}
// If you have set NoFreeze, you may not clear GlobalFreeze
// This prevents those who have set NoFreeze from using
// GlobalFreeze strategically.
if ((uSetFlag != asfGlobalFreeze) && (uClearFlag == asfGlobalFreeze) &&
((uFlagsOut & lsfNoFreeze) == 0))
{
m_journal.trace << "Clear GlobalFreeze flag";
uFlagsOut &= ~lsfGlobalFreeze;
}
//
// Track transaction IDs signed by this account in its root
//
if ((uSetFlag == asfAccountTxnID) && (uClearFlag != asfAccountTxnID) && !mTxnAccount->isFieldPresent (sfAccountTxnID))
{
m_journal.trace << "Set AccountTxnID";
mTxnAccount->makeFieldPresent (sfAccountTxnID);
}
if ((uClearFlag == asfAccountTxnID) && (uSetFlag != asfAccountTxnID) && mTxnAccount->isFieldPresent (sfAccountTxnID))
{
m_journal.trace << "Clear AccountTxnID";
mTxnAccount->makeFieldAbsent (sfAccountTxnID);
}
//
// EmailHash
//
if (mTxn.isFieldPresent (sfEmailHash))
{
uint128 uHash = mTxn.getFieldH128 (sfEmailHash);
if (!uHash)
{
m_journal.trace << "unset email hash";
mTxnAccount->makeFieldAbsent (sfEmailHash);
}
else
{
m_journal.trace << "set email hash";
mTxnAccount->setFieldH128 (sfEmailHash, uHash);
}
}
//
// WalletLocator
//
if (mTxn.isFieldPresent (sfWalletLocator))
{
uint256 uHash = mTxn.getFieldH256 (sfWalletLocator);
if (!uHash)
{
m_journal.trace << "unset wallet locator";
mTxnAccount->makeFieldAbsent (sfEmailHash);
}
else
{
m_journal.trace << "set wallet locator";
mTxnAccount->setFieldH256 (sfWalletLocator, uHash);
}
}
//
// MessageKey
//
if (mTxn.isFieldPresent (sfMessageKey))
{
Blob vucPublic = mTxn.getFieldVL (sfMessageKey);
if (vucPublic.empty ())
{
m_journal.debug << "set message key";
mTxnAccount->makeFieldAbsent (sfMessageKey);
}
if (vucPublic.size () > PUBLIC_BYTES_MAX)
{
m_journal.trace << "message key too long";
return telBAD_PUBLIC_KEY;
}
else
{
m_journal.debug << "set message key";
mTxnAccount->setFieldVL (sfMessageKey, vucPublic);
}
}
//
// Domain
//
if (mTxn.isFieldPresent (sfDomain))
{
Blob vucDomain = mTxn.getFieldVL (sfDomain);
if (vucDomain.empty ())
{
m_journal.trace << "unset domain";
mTxnAccount->makeFieldAbsent (sfDomain);
}
else if (vucDomain.size () > DOMAIN_BYTES_MAX)
{
m_journal.trace << "domain too long";
return telBAD_DOMAIN;
}
else
{
m_journal.trace << "set domain";
mTxnAccount->setFieldVL (sfDomain, vucDomain);
}
}
//
// TransferRate
//
if (mTxn.isFieldPresent (sfTransferRate))
{
std::uint32_t uRate = mTxn.getFieldU32 (sfTransferRate);
if (!uRate || uRate == QUALITY_ONE)
{
m_journal.trace << "unset transfer rate";
mTxnAccount->makeFieldAbsent (sfTransferRate);
}
else if (uRate > QUALITY_ONE)
{
m_journal.trace << "set transfer rate";
mTxnAccount->setFieldU32 (sfTransferRate, uRate);
}
else
{
m_journal.trace << "bad transfer rate";
return temBAD_TRANSFER_RATE;
}
}
if (uFlagsIn != uFlagsOut)
mTxnAccount->setFieldU32 (sfFlags, uFlagsOut);
return tesSUCCESS;
}
};
//
// WalletLocator
//
if (mTxn.isFieldPresent (sfWalletLocator))
{
uint256 uHash = mTxn.getFieldH256 (sfWalletLocator);
if (!uHash)
{
m_journal.trace << "unset wallet locator";
mTxnAccount->makeFieldAbsent (sfEmailHash);
}
else
{
m_journal.trace << "set wallet locator";
mTxnAccount->setFieldH256 (sfWalletLocator, uHash);
}
}
//
// MessageKey
//
if (mTxn.isFieldPresent (sfMessageKey))
{
Blob vucPublic = mTxn.getFieldVL (sfMessageKey);
if (vucPublic.empty ())
{
m_journal.debug << "set message key";
mTxnAccount->makeFieldAbsent (sfMessageKey);
}
if (vucPublic.size () > PUBLIC_BYTES_MAX)
{
m_journal.trace << "message key too long";
return telBAD_PUBLIC_KEY;
}
else
{
m_journal.debug << "set message key";
mTxnAccount->setFieldVL (sfMessageKey, vucPublic);
}
}
//
// Domain
//
if (mTxn.isFieldPresent (sfDomain))
{
Blob vucDomain = mTxn.getFieldVL (sfDomain);
if (vucDomain.empty ())
{
m_journal.trace << "unset domain";
mTxnAccount->makeFieldAbsent (sfDomain);
}
else if (vucDomain.size () > DOMAIN_BYTES_MAX)
{
m_journal.trace << "domain too long";
return telBAD_DOMAIN;
}
else
{
m_journal.trace << "set domain";
mTxnAccount->setFieldVL (sfDomain, vucDomain);
}
}
//
// TransferRate
//
if (mTxn.isFieldPresent (sfTransferRate))
{
std::uint32_t uRate = mTxn.getFieldU32 (sfTransferRate);
if (!uRate || uRate == QUALITY_ONE)
{
m_journal.trace << "unset transfer rate";
mTxnAccount->makeFieldAbsent (sfTransferRate);
}
else if (uRate > QUALITY_ONE)
{
m_journal.trace << "set transfer rate";
mTxnAccount->setFieldU32 (sfTransferRate, uRate);
}
else
{
m_journal.trace << "bad transfer rate";
return temBAD_TRANSFER_RATE;
}
}
if (uFlagsIn != uFlagsOut)
mTxnAccount->setFieldU32 (sfFlags, uFlagsOut);
return tesSUCCESS;
TER
transact_SetAccount (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return SetAccount(txn, params, engine).apply ();
}
}

View File

@@ -1,57 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_ACCOUNTSET_H_INCLUDED
#define RIPPLE_TX_ACCOUNTSET_H_INCLUDED
namespace ripple {
class SetAccount
: public Transactor
{
public:
SetAccount (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("SetAccount"))
{
}
TER doApply () override;
};
inline
std::unique_ptr <Transactor>
make_SetAccount (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <SetAccount> (txn, params, engine);
}
}
#endif

View File

@@ -19,50 +19,76 @@
namespace ripple {
std::uint64_t SetRegularKey::calculateBaseFee ()
class SetRegularKey
: public Transactor
{
if ( mTxnAccount
&& (! (mTxnAccount->getFlags () & lsfPasswordSpent))
&& (mSigningPubKey.getAccountID () == mTxnAccountID))
std::uint64_t calculateBaseFee () override
{
// flag is armed and they signed with the right account
return 0;
if ( mTxnAccount
&& (! (mTxnAccount->getFlags () & lsfPasswordSpent))
&& (mSigningPubKey.getAccountID () == mTxnAccountID))
{
// flag is armed and they signed with the right account
return 0;
}
return Transactor::calculateBaseFee ();
}
return Transactor::calculateBaseFee ();
}
public:
SetRegularKey (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("SetRegularKey"))
{
}
TER SetRegularKey::doApply ()
TER doApply () override
{
std::uint32_t const uTxFlags = mTxn.getFlags ();
if (uTxFlags & tfUniversalMask)
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
if (mFeeDue == zero)
{
mTxnAccount->setFlag (lsfPasswordSpent);
}
if (mTxn.isFieldPresent (sfRegularKey))
{
Account uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey);
mTxnAccount->setFieldAccount (sfRegularKey, uAuthKeyID);
}
else
{
if (mTxnAccount->isFlag (lsfDisableMaster))
return tecMASTER_DISABLED;
mTxnAccount->makeFieldAbsent (sfRegularKey);
}
return tesSUCCESS;
}
};
TER
transact_SetRegularKey (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
std::uint32_t const uTxFlags = mTxn.getFlags ();
if (uTxFlags & tfUniversalMask)
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
if (mFeeDue == zero)
{
mTxnAccount->setFlag (lsfPasswordSpent);
}
if (mTxn.isFieldPresent (sfRegularKey))
{
Account uAuthKeyID = mTxn.getFieldAccount160 (sfRegularKey);
mTxnAccount->setFieldAccount (sfRegularKey, uAuthKeyID);
}
else
{
if (mTxnAccount->isFlag (lsfDisableMaster))
return tecMASTER_DISABLED;
mTxnAccount->makeFieldAbsent (sfRegularKey);
}
return tesSUCCESS;
return SetRegularKey(txn, params, engine).apply ();
}
}

View File

@@ -1,60 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_REGULARSETKEY_H_INCLUDED
#define RIPPLE_TX_REGULARSETKEY_H_INCLUDED
namespace ripple {
class SetRegularKey
: public Transactor
{
std::uint64_t calculateBaseFee ();
public:
SetRegularKey (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("SetRegularKey"))
{
}
TER checkFee ();
TER doApply ();
};
inline
std::unique_ptr <Transactor>
make_SetRegularKey (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <SetRegularKey> (txn, params, engine);
}
}
#endif

View File

@@ -19,383 +19,417 @@
namespace ripple {
TER SetTrust::doApply ()
class SetTrust
: public Transactor
{
TER terResult = tesSUCCESS;
STAmount const saLimitAmount (mTxn.getFieldAmount (sfLimitAmount));
bool const bQualityIn (mTxn.isFieldPresent (sfQualityIn));
bool const bQualityOut (mTxn.isFieldPresent (sfQualityOut));
Currency const currency (saLimitAmount.getCurrency ());
Account uDstAccountID (saLimitAmount.getIssuer ());
// true, iff current is high account.
bool const bHigh = mTxnAccountID > uDstAccountID;
std::uint32_t uQualityIn (bQualityIn ? mTxn.getFieldU32 (sfQualityIn) : 0);
std::uint32_t uQualityOut (bQualityOut ? mTxn.getFieldU32 (sfQualityOut) : 0);
if (!saLimitAmount.isLegalNet ())
return temBAD_AMOUNT;
if (bQualityIn && QUALITY_ONE == uQualityIn)
uQualityIn = 0;
if (bQualityOut && QUALITY_ONE == uQualityOut)
uQualityOut = 0;
std::uint32_t const uTxFlags = mTxn.getFlags ();
if (uTxFlags & tfTrustSetMask)
public:
SetTrust (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("SetTrust"))
{
m_journal.trace <<
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
bool const bSetAuth = (uTxFlags & tfSetfAuth);
bool const bSetNoRipple = (uTxFlags & tfSetNoRipple);
bool const bClearNoRipple = (uTxFlags & tfClearNoRipple);
bool const bSetFreeze = (uTxFlags & tfSetFreeze);
bool const bClearFreeze = (uTxFlags & tfClearFreeze);
if (bSetAuth && !(mTxnAccount->getFieldU32 (sfFlags) & lsfRequireAuth))
TER doApply () override
{
m_journal.trace <<
"Retry: Auth not required.";
return tefNO_AUTH_REQUIRED;
}
TER terResult = tesSUCCESS;
if (saLimitAmount.isNative ())
{
m_journal.trace <<
"Malformed transaction: Native credit limit: " <<
saLimitAmount.getFullText ();
return temBAD_LIMIT;
}
STAmount const saLimitAmount (mTxn.getFieldAmount (sfLimitAmount));
bool const bQualityIn (mTxn.isFieldPresent (sfQualityIn));
bool const bQualityOut (mTxn.isFieldPresent (sfQualityOut));
if (saLimitAmount < zero)
{
m_journal.trace <<
"Malformed transaction: Negative credit limit.";
return temBAD_LIMIT;
}
Currency const currency (saLimitAmount.getCurrency ());
Account uDstAccountID (saLimitAmount.getIssuer ());
// Check if destination makes sense.
if (!uDstAccountID || uDstAccountID == noAccount())
{
m_journal.trace <<
"Malformed transaction: Destination account not specified.";
// true, iff current is high account.
bool const bHigh = mTxnAccountID > uDstAccountID;
return temDST_NEEDED;
}
std::uint32_t const uOwnerCount (mTxnAccount->getFieldU32 (sfOwnerCount));
// The reserve required to create the line. Note that we allow up to
// two trust lines without requiring a reserve because being able to
// exchange currencies is a powerful Ripple feature.
//
// This is also a security feature: if you're a gateway and you want to
// be able to let someone use your services, you would otherwise have to
// give them enough XRP to cover the incremental reserve for their trust
// line. If they had no intention of using your services, they could use
// the XRP for their own purposes. So we make it possible for gateways
// to fund accounts in a way where there's no incentive to trick them
// into creating an account you have no intention of using.
if (mTxnAccountID == uDstAccountID)
{
SLE::pointer selDelete (
mEngine->entryCache (ltRIPPLE_STATE,
Ledger::getRippleStateIndex (
mTxnAccountID, uDstAccountID, currency)));
if (selDelete)
{
m_journal.warning <<
"Clearing redundant line.";
return mEngine->view ().trustDelete (
selDelete, mTxnAccountID, uDstAccountID);
}
else
{
m_journal.trace <<
"Malformed transaction: Can not extend credit to self.";
return temDST_IS_SRC;
}
}
SLE::pointer sleDst (mEngine->entryCache (
ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)));
if (!sleDst)
{
m_journal.trace <<
"Delay transaction: Destination account does not exist.";
return tecNO_DST;
}
std::uint32_t const uOwnerCount (mTxnAccount->getFieldU32 (sfOwnerCount));
// The reserve required to create the line.
std::uint64_t const uReserveCreate =
(uOwnerCount < 2)
std::uint64_t const uReserveCreate = (uOwnerCount < 2)
? 0
: mEngine->getLedger ()->getReserve (uOwnerCount + 1);
STAmount saLimitAllow = saLimitAmount;
saLimitAllow.setIssuer (mTxnAccountID);
std::uint32_t uQualityIn (bQualityIn ? mTxn.getFieldU32 (sfQualityIn) : 0);
std::uint32_t uQualityOut (bQualityOut ? mTxn.getFieldU32 (sfQualityOut) : 0);
SLE::pointer sleRippleState (mEngine->entryCache (ltRIPPLE_STATE,
Ledger::getRippleStateIndex (mTxnAccountID, uDstAccountID, currency)));
if (!saLimitAmount.isLegalNet ())
return temBAD_AMOUNT;
if (sleRippleState)
{
STAmount saLowBalance;
STAmount saLowLimit;
STAmount saHighBalance;
STAmount saHighLimit;
std::uint32_t uLowQualityIn;
std::uint32_t uLowQualityOut;
std::uint32_t uHighQualityIn;
std::uint32_t uHighQualityOut;
auto const& uLowAccountID = !bHigh ? mTxnAccountID : uDstAccountID;
auto const& uHighAccountID = bHigh ? mTxnAccountID : uDstAccountID;
SLE::ref sleLowAccount = !bHigh ? mTxnAccount : sleDst;
SLE::ref sleHighAccount = bHigh ? mTxnAccount : sleDst;
if (bQualityOut && QUALITY_ONE == uQualityOut)
uQualityOut = 0;
//
// Balances
//
std::uint32_t const uTxFlags = mTxn.getFlags ();
saLowBalance = sleRippleState->getFieldAmount (sfBalance);
saHighBalance = -saLowBalance;
//
// Limits
//
sleRippleState->setFieldAmount (!bHigh ? sfLowLimit : sfHighLimit, saLimitAllow);
saLowLimit = !bHigh ? saLimitAllow : sleRippleState->getFieldAmount (sfLowLimit);
saHighLimit = bHigh ? saLimitAllow : sleRippleState->getFieldAmount (sfHighLimit);
//
// Quality in
//
if (!bQualityIn)
{
// Not setting. Just get it.
uLowQualityIn = sleRippleState->getFieldU32 (sfLowQualityIn);
uHighQualityIn = sleRippleState->getFieldU32 (sfHighQualityIn);
}
else if (uQualityIn)
{
// Setting.
sleRippleState->setFieldU32 (!bHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
uLowQualityIn = !bHigh ? uQualityIn : sleRippleState->getFieldU32 (sfLowQualityIn);
uHighQualityIn = bHigh ? uQualityIn : sleRippleState->getFieldU32 (sfHighQualityIn);
}
else
{
// Clearing.
sleRippleState->makeFieldAbsent (!bHigh ? sfLowQualityIn : sfHighQualityIn);
uLowQualityIn = !bHigh ? 0 : sleRippleState->getFieldU32 (sfLowQualityIn);
uHighQualityIn = bHigh ? 0 : sleRippleState->getFieldU32 (sfHighQualityIn);
}
if (QUALITY_ONE == uLowQualityIn) uLowQualityIn = 0;
if (QUALITY_ONE == uHighQualityIn) uHighQualityIn = 0;
//
// Quality out
//
if (!bQualityOut)
{
// Not setting. Just get it.
uLowQualityOut = sleRippleState->getFieldU32 (sfLowQualityOut);
uHighQualityOut = sleRippleState->getFieldU32 (sfHighQualityOut);
}
else if (uQualityOut)
{
// Setting.
sleRippleState->setFieldU32 (!bHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
uLowQualityOut = !bHigh ? uQualityOut : sleRippleState->getFieldU32 (sfLowQualityOut);
uHighQualityOut = bHigh ? uQualityOut : sleRippleState->getFieldU32 (sfHighQualityOut);
}
else
{
// Clearing.
sleRippleState->makeFieldAbsent (!bHigh ? sfLowQualityOut : sfHighQualityOut);
uLowQualityOut = !bHigh ? 0 : sleRippleState->getFieldU32 (sfLowQualityOut);
uHighQualityOut = bHigh ? 0 : sleRippleState->getFieldU32 (sfHighQualityOut);
}
std::uint32_t const uFlagsIn (sleRippleState->getFieldU32 (sfFlags));
std::uint32_t uFlagsOut (uFlagsIn);
if (bSetNoRipple && !bClearNoRipple && (bHigh ? saHighBalance : saLowBalance) >= zero)
{
uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple);
}
else if (bClearNoRipple && !bSetNoRipple)
{
uFlagsOut &= ~(bHigh ? lsfHighNoRipple : lsfLowNoRipple);
}
if (bSetFreeze && !bClearFreeze && !mTxnAccount->isFlag (lsfNoFreeze))
{
uFlagsOut |= (bHigh ? lsfHighFreeze : lsfLowFreeze);
}
else if (bClearFreeze && !bSetFreeze)
{
uFlagsOut &= ~(bHigh ? lsfHighFreeze : lsfLowFreeze);
}
if (QUALITY_ONE == uLowQualityOut) uLowQualityOut = 0;
if (QUALITY_ONE == uHighQualityOut) uHighQualityOut = 0;
bool const bLowReserveSet = uLowQualityIn || uLowQualityOut ||
(uFlagsOut & lsfLowNoRipple) ||
(uFlagsOut & lsfLowFreeze) ||
saLowLimit || saLowBalance > zero;
bool const bLowReserveClear = !bLowReserveSet;
bool const bHighReserveSet = uHighQualityIn || uHighQualityOut ||
(uFlagsOut & lsfHighNoRipple) ||
(uFlagsOut & lsfHighFreeze) ||
saHighLimit || saHighBalance > zero;
bool const bHighReserveClear = !bHighReserveSet;
bool const bDefault = bLowReserveClear && bHighReserveClear;
bool const bLowReserved = (uFlagsIn & lsfLowReserve);
bool const bHighReserved = (uFlagsIn & lsfHighReserve);
bool bReserveIncrease = false;
if (bSetAuth)
{
uFlagsOut |= (bHigh ? lsfHighAuth : lsfLowAuth);
}
if (bLowReserveSet && !bLowReserved)
{
// Set reserve for low account.
mEngine->view ().ownerCountAdjust (uLowAccountID, 1, sleLowAccount);
uFlagsOut |= lsfLowReserve;
if (!bHigh)
bReserveIncrease = true;
}
if (bLowReserveClear && bLowReserved)
{
// Clear reserve for low account.
mEngine->view ().ownerCountAdjust (uLowAccountID, -1, sleLowAccount);
uFlagsOut &= ~lsfLowReserve;
}
if (bHighReserveSet && !bHighReserved)
{
// Set reserve for high account.
mEngine->view ().ownerCountAdjust (uHighAccountID, 1, sleHighAccount);
uFlagsOut |= lsfHighReserve;
if (bHigh)
bReserveIncrease = true;
}
if (bHighReserveClear && bHighReserved)
{
// Clear reserve for high account.
mEngine->view ().ownerCountAdjust (uHighAccountID, -1, sleHighAccount);
uFlagsOut &= ~lsfHighReserve;
}
if (uFlagsIn != uFlagsOut)
sleRippleState->setFieldU32 (sfFlags, uFlagsOut);
if (bDefault || badCurrency() == currency)
{
// Delete.
terResult = mEngine->view ().trustDelete (sleRippleState, uLowAccountID, uHighAccountID);
}
else if (bReserveIncrease
&& mPriorBalance.getNValue () < uReserveCreate) // Reserve is not scaled by load.
if (uTxFlags & tfTrustSetMask)
{
m_journal.trace <<
"Delay transaction: Insufficent reserve to add trust line.";
"Malformed transaction: Invalid flags set.";
return temINVALID_FLAG;
}
// Another transaction could provide XRP to the account and then
// this transaction would succeed.
terResult = tecINSUF_RESERVE_LINE;
bool const bSetAuth = (uTxFlags & tfSetfAuth);
bool const bSetNoRipple = (uTxFlags & tfSetNoRipple);
bool const bClearNoRipple = (uTxFlags & tfClearNoRipple);
bool const bSetFreeze = (uTxFlags & tfSetFreeze);
bool const bClearFreeze = (uTxFlags & tfClearFreeze);
if (bSetAuth && !(mTxnAccount->getFieldU32 (sfFlags) & lsfRequireAuth))
{
m_journal.trace <<
"Retry: Auth not required.";
return tefNO_AUTH_REQUIRED;
}
if (saLimitAmount.isNative ())
{
m_journal.trace <<
"Malformed transaction: Native credit limit: " <<
saLimitAmount.getFullText ();
return temBAD_LIMIT;
}
if (saLimitAmount < zero)
{
m_journal.trace <<
"Malformed transaction: Negative credit limit.";
return temBAD_LIMIT;
}
// Check if destination makes sense.
if (!uDstAccountID || uDstAccountID == noAccount())
{
m_journal.trace <<
"Malformed transaction: Destination account not specified.";
return temDST_NEEDED;
}
if (mTxnAccountID == uDstAccountID)
{
SLE::pointer selDelete (
mEngine->entryCache (ltRIPPLE_STATE,
Ledger::getRippleStateIndex (
mTxnAccountID, uDstAccountID, currency)));
if (selDelete)
{
m_journal.warning <<
"Clearing redundant line.";
return mEngine->view ().trustDelete (
selDelete, mTxnAccountID, uDstAccountID);
}
else
{
m_journal.trace <<
"Malformed transaction: Can not extend credit to self.";
return temDST_IS_SRC;
}
}
SLE::pointer sleDst (mEngine->entryCache (
ltACCOUNT_ROOT, Ledger::getAccountRootIndex (uDstAccountID)));
if (!sleDst)
{
m_journal.trace <<
"Delay transaction: Destination account does not exist.";
return tecNO_DST;
}
STAmount saLimitAllow = saLimitAmount;
saLimitAllow.setIssuer (mTxnAccountID);
SLE::pointer sleRippleState (mEngine->entryCache (ltRIPPLE_STATE,
Ledger::getRippleStateIndex (mTxnAccountID, uDstAccountID, currency)));
if (sleRippleState)
{
STAmount saLowBalance;
STAmount saLowLimit;
STAmount saHighBalance;
STAmount saHighLimit;
std::uint32_t uLowQualityIn;
std::uint32_t uLowQualityOut;
std::uint32_t uHighQualityIn;
std::uint32_t uHighQualityOut;
auto const& uLowAccountID = !bHigh ? mTxnAccountID : uDstAccountID;
auto const& uHighAccountID = bHigh ? mTxnAccountID : uDstAccountID;
SLE::ref sleLowAccount = !bHigh ? mTxnAccount : sleDst;
SLE::ref sleHighAccount = bHigh ? mTxnAccount : sleDst;
//
// Balances
//
saLowBalance = sleRippleState->getFieldAmount (sfBalance);
saHighBalance = -saLowBalance;
//
// Limits
//
sleRippleState->setFieldAmount (!bHigh ? sfLowLimit : sfHighLimit, saLimitAllow);
saLowLimit = !bHigh ? saLimitAllow : sleRippleState->getFieldAmount (sfLowLimit);
saHighLimit = bHigh ? saLimitAllow : sleRippleState->getFieldAmount (sfHighLimit);
//
// Quality in
//
if (!bQualityIn)
{
// Not setting. Just get it.
uLowQualityIn = sleRippleState->getFieldU32 (sfLowQualityIn);
uHighQualityIn = sleRippleState->getFieldU32 (sfHighQualityIn);
}
else if (uQualityIn)
{
// Setting.
sleRippleState->setFieldU32 (!bHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn);
uLowQualityIn = !bHigh ? uQualityIn : sleRippleState->getFieldU32 (sfLowQualityIn);
uHighQualityIn = bHigh ? uQualityIn : sleRippleState->getFieldU32 (sfHighQualityIn);
}
else
{
// Clearing.
sleRippleState->makeFieldAbsent (!bHigh ? sfLowQualityIn : sfHighQualityIn);
uLowQualityIn = !bHigh ? 0 : sleRippleState->getFieldU32 (sfLowQualityIn);
uHighQualityIn = bHigh ? 0 : sleRippleState->getFieldU32 (sfHighQualityIn);
}
if (QUALITY_ONE == uLowQualityIn) uLowQualityIn = 0;
if (QUALITY_ONE == uHighQualityIn) uHighQualityIn = 0;
//
// Quality out
//
if (!bQualityOut)
{
// Not setting. Just get it.
uLowQualityOut = sleRippleState->getFieldU32 (sfLowQualityOut);
uHighQualityOut = sleRippleState->getFieldU32 (sfHighQualityOut);
}
else if (uQualityOut)
{
// Setting.
sleRippleState->setFieldU32 (!bHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut);
uLowQualityOut = !bHigh ? uQualityOut : sleRippleState->getFieldU32 (sfLowQualityOut);
uHighQualityOut = bHigh ? uQualityOut : sleRippleState->getFieldU32 (sfHighQualityOut);
}
else
{
// Clearing.
sleRippleState->makeFieldAbsent (!bHigh ? sfLowQualityOut : sfHighQualityOut);
uLowQualityOut = !bHigh ? 0 : sleRippleState->getFieldU32 (sfLowQualityOut);
uHighQualityOut = bHigh ? 0 : sleRippleState->getFieldU32 (sfHighQualityOut);
}
std::uint32_t const uFlagsIn (sleRippleState->getFieldU32 (sfFlags));
std::uint32_t uFlagsOut (uFlagsIn);
if (bSetNoRipple && !bClearNoRipple && (bHigh ? saHighBalance : saLowBalance) >= zero)
{
uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple);
}
else if (bClearNoRipple && !bSetNoRipple)
{
uFlagsOut &= ~(bHigh ? lsfHighNoRipple : lsfLowNoRipple);
}
if (bSetFreeze && !bClearFreeze && !mTxnAccount->isFlag (lsfNoFreeze))
{
uFlagsOut |= (bHigh ? lsfHighFreeze : lsfLowFreeze);
}
else if (bClearFreeze && !bSetFreeze)
{
uFlagsOut &= ~(bHigh ? lsfHighFreeze : lsfLowFreeze);
}
if (QUALITY_ONE == uLowQualityOut) uLowQualityOut = 0;
if (QUALITY_ONE == uHighQualityOut) uHighQualityOut = 0;
bool const bLowReserveSet = uLowQualityIn || uLowQualityOut ||
(uFlagsOut & lsfLowNoRipple) ||
(uFlagsOut & lsfLowFreeze) ||
saLowLimit || saLowBalance > zero;
bool const bLowReserveClear = !bLowReserveSet;
bool const bHighReserveSet = uHighQualityIn || uHighQualityOut ||
(uFlagsOut & lsfHighNoRipple) ||
(uFlagsOut & lsfHighFreeze) ||
saHighLimit || saHighBalance > zero;
bool const bHighReserveClear = !bHighReserveSet;
bool const bDefault = bLowReserveClear && bHighReserveClear;
bool const bLowReserved = (uFlagsIn & lsfLowReserve);
bool const bHighReserved = (uFlagsIn & lsfHighReserve);
bool bReserveIncrease = false;
if (bSetAuth)
{
uFlagsOut |= (bHigh ? lsfHighAuth : lsfLowAuth);
}
if (bLowReserveSet && !bLowReserved)
{
// Set reserve for low account.
mEngine->view ().ownerCountAdjust (uLowAccountID, 1, sleLowAccount);
uFlagsOut |= lsfLowReserve;
if (!bHigh)
bReserveIncrease = true;
}
if (bLowReserveClear && bLowReserved)
{
// Clear reserve for low account.
mEngine->view ().ownerCountAdjust (uLowAccountID, -1, sleLowAccount);
uFlagsOut &= ~lsfLowReserve;
}
if (bHighReserveSet && !bHighReserved)
{
// Set reserve for high account.
mEngine->view ().ownerCountAdjust (uHighAccountID, 1, sleHighAccount);
uFlagsOut |= lsfHighReserve;
if (bHigh)
bReserveIncrease = true;
}
if (bHighReserveClear && bHighReserved)
{
// Clear reserve for high account.
mEngine->view ().ownerCountAdjust (uHighAccountID, -1, sleHighAccount);
uFlagsOut &= ~lsfHighReserve;
}
if (uFlagsIn != uFlagsOut)
sleRippleState->setFieldU32 (sfFlags, uFlagsOut);
if (bDefault || badCurrency() == currency)
{
// Delete.
terResult = mEngine->view ().trustDelete (sleRippleState, uLowAccountID, uHighAccountID);
}
else if (bReserveIncrease
&& mPriorBalance.getNValue () < uReserveCreate) // Reserve is not scaled by load.
{
m_journal.trace <<
"Delay transaction: Insufficent reserve to add trust line.";
// Another transaction could provide XRP to the account and then
// this transaction would succeed.
terResult = tecINSUF_RESERVE_LINE;
}
else
{
mEngine->entryModify (sleRippleState);
m_journal.trace << "Modify ripple line";
}
}
// Line does not exist.
else if (!saLimitAmount // Setting default limit.
&& (!bQualityIn || !uQualityIn) // Not setting quality in or setting default quality in.
&& (!bQualityOut || !uQualityOut)) // Not setting quality out or setting default quality out.
{
m_journal.trace <<
"Redundant: Setting non-existent ripple line to defaults.";
return tecNO_LINE_REDUNDANT;
}
else if (mPriorBalance.getNValue () < uReserveCreate) // Reserve is not scaled by load.
{
m_journal.trace <<
"Delay transaction: Line does not exist. Insufficent reserve to create line.";
// Another transaction could create the account and then this transaction would succeed.
terResult = tecNO_LINE_INSUF_RESERVE;
}
else if (badCurrency() == currency)
{
terResult = temBAD_CURRENCY;
}
else
{
mEngine->entryModify (sleRippleState);
// Zero balance in currency.
STAmount saBalance ({currency, noAccount()});
m_journal.trace << "Modify ripple line";
uint256 index (Ledger::getRippleStateIndex (
mTxnAccountID, uDstAccountID, currency));
m_journal.trace <<
"doTrustSet: Creating ripple line: " <<
to_string (index);
// Create a new ripple line.
terResult = mEngine->view ().trustCreate (
bHigh,
mTxnAccountID,
uDstAccountID,
index,
mTxnAccount,
bSetAuth,
bSetNoRipple && !bClearNoRipple,
bSetFreeze && !bClearFreeze,
saBalance,
saLimitAllow, // Limit for who is being charged.
uQualityIn,
uQualityOut);
}
}
// Line does not exist.
else if (!saLimitAmount // Setting default limit.
&& (!bQualityIn || !uQualityIn) // Not setting quality in or setting default quality in.
&& (!bQualityOut || !uQualityOut)) // Not setting quality out or setting default quality out.
{
m_journal.trace <<
"Redundant: Setting non-existent ripple line to defaults.";
return tecNO_LINE_REDUNDANT;
}
else if (mPriorBalance.getNValue () < uReserveCreate) // Reserve is not scaled by load.
{
m_journal.trace <<
"Delay transaction: Line does not exist. Insufficent reserve to create line.";
// Another transaction could create the account and then this transaction would succeed.
terResult = tecNO_LINE_INSUF_RESERVE;
return terResult;
}
else if (badCurrency() == currency)
{
terResult = temBAD_CURRENCY;
}
else
{
// Zero balance in currency.
STAmount saBalance ({currency, noAccount()});
};
uint256 index (Ledger::getRippleStateIndex (
mTxnAccountID, uDstAccountID, currency));
m_journal.trace <<
"doTrustSet: Creating ripple line: " <<
to_string (index);
// Create a new ripple line.
terResult = mEngine->view ().trustCreate (
bHigh,
mTxnAccountID,
uDstAccountID,
index,
mTxnAccount,
bSetAuth,
bSetNoRipple && !bClearNoRipple,
bSetFreeze && !bClearFreeze,
saBalance,
saLimitAllow, // Limit for who is being charged.
uQualityIn,
uQualityOut);
}
return terResult;
TER
transact_SetTrust (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return SetTrust (txn, params, engine).apply ();
}
}

View File

@@ -1,56 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_TX_TRUSTSET_H_INCLUDED
#define RIPPLE_TX_TRUSTSET_H_INCLUDED
namespace ripple {
class SetTrust
: public Transactor
{
public:
SetTrust (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
: Transactor (
txn,
params,
engine,
deprecatedLogs().journal("SetTrust"))
{
}
TER doApply ();
};
inline
std::unique_ptr <Transactor>
make_SetTrust (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
{
return std::make_unique <SetTrust> (txn, params, engine);
}
}
#endif

View File

@@ -18,18 +18,20 @@
//==============================================================================
#include <ripple/module/app/transactors/Transactor.h>
#include <ripple/module/app/transactors/AddWallet.h>
#include <ripple/module/app/transactors/CancelOffer.h>
#include <ripple/module/app/transactors/Change.h>
#include <ripple/module/app/transactors/CreateOffer.h>
#include <ripple/module/app/transactors/Payment.h>
#include <ripple/module/app/transactors/SetAccount.h>
#include <ripple/module/app/transactors/SetRegularKey.h>
#include <ripple/module/app/transactors/SetTrust.h>
namespace ripple {
std::unique_ptr<Transactor> Transactor::makeTransactor (
TER transact_Payment (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_SetAccount (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_SetRegularKey (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_SetTrust (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_CreateOffer (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_CancelOffer (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_AddWallet (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER transact_Change (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
TER
Transactor::transact (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine)
@@ -37,36 +39,35 @@ std::unique_ptr<Transactor> Transactor::makeTransactor (
switch (txn.getTxnType ())
{
case ttPAYMENT:
return make_Payment (txn, params, engine);
return transact_Payment (txn, params, engine);
case ttACCOUNT_SET:
return make_SetAccount (txn, params, engine);
return transact_SetAccount (txn, params, engine);
case ttREGULAR_KEY_SET:
return make_SetRegularKey (txn, params, engine);
return transact_SetRegularKey (txn, params, engine);
case ttTRUST_SET:
return make_SetTrust (txn, params, engine);
return transact_SetTrust (txn, params, engine);
case ttOFFER_CREATE:
return make_CreateOffer (txn, params, engine);
return transact_CreateOffer (txn, params, engine);
case ttOFFER_CANCEL:
return make_CancelOffer (txn, params, engine);
return transact_CancelOffer (txn, params, engine);
case ttWALLET_ADD:
return make_AddWallet (txn, params, engine);
return transact_AddWallet (txn, params, engine);
case ttAMENDMENT:
case ttFEE:
return make_Change (txn, params, engine);
return transact_Change (txn, params, engine);
default:
return std::unique_ptr<Transactor> ();
return temUNKNOWN;
}
}
Transactor::Transactor (
SerializedTransaction const& txn,
TransactionEngineParams params,

View File

@@ -25,12 +25,15 @@ namespace ripple {
class Transactor
{
public:
static std::unique_ptr<Transactor> makeTransactor (
static
TER
transact (
SerializedTransaction const& txn,
TransactionEngineParams params,
TransactionEngine* engine);
TER apply ();
TER
apply ();
protected:
SerializedTransaction const& mTxn;

View File

@@ -70,8 +70,10 @@ void TransactionEngine::txnWrite ()
}
}
TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, TransactionEngineParams params,
bool& didApply)
TER TransactionEngine::applyTransaction (
SerializedTransaction const& txn,
TransactionEngineParams params,
bool& didApply)
{
WriteLog (lsTRACE, TransactionEngine) << "applyTransaction>";
didApply = false;
@@ -79,7 +81,6 @@ TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, Trans
mNodes.init (mLedger, txn.getTransactionID (), mLedger->getLedgerSeq (), params);
#ifdef BEAST_DEBUG
if (1)
{
Serializer ser;
@@ -89,39 +90,46 @@ TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, Trans
if (!s2.isEquivalent (txn))
{
WriteLog (lsFATAL, TransactionEngine) << "Transaction serdes mismatch";
WriteLog (lsFATAL, TransactionEngine) <<
"Transaction serdes mismatch";
Json::StyledStreamWriter ssw;
WriteLog (lsINFO, TransactionEngine) << txn.getJson (0);
WriteLog (lsFATAL, TransactionEngine) << s2.getJson (0);
assert (false);
}
}
#endif
uint256 txID = txn.getTransactionID ();
if (!txID)
{
WriteLog (lsWARNING, TransactionEngine) << "applyTransaction: invalid transaction id";
WriteLog (lsWARNING, TransactionEngine) <<
"applyTransaction: invalid transaction id";
return temINVALID;
}
std::unique_ptr<Transactor> transactor = Transactor::makeTransactor (txn, params, this);
TER terResult = Transactor::transact (txn, params, this);
if (transactor.get () == nullptr)
if (terResult == temUNKNOWN)
{
WriteLog (lsWARNING, TransactionEngine) << "applyTransaction: Invalid transaction: unknown transaction type";
WriteLog (lsWARNING, TransactionEngine) <<
"applyTransaction: Invalid transaction: unknown transaction type";
return temUNKNOWN;
}
TER terResult = transactor->apply ();
std::string strToken;
std::string strHuman;
if (ShouldLog (lsINFO, TransactionEngine))
{
std::string strToken;
std::string strHuman;
transResultInfo (terResult, strToken, strHuman);
transResultInfo (terResult, strToken, strHuman);
WriteLog (lsINFO, TransactionEngine) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman;
WriteLog (lsINFO, TransactionEngine) <<
"applyTransaction: terResult=" << strToken <<
" : " << terResult <<
" : " << strHuman;
}
if (isTesSuccess (terResult))
didApply = true;
@@ -131,7 +139,8 @@ TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, Trans
WriteLog (lsDEBUG, TransactionEngine) << "Reprocessing to only claim fee";
mNodes.clear ();
SLE::pointer txnAcct = entryCache (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (txn.getSourceAccount ()));
SLE::pointer txnAcct = entryCache (ltACCOUNT_ROOT,
Ledger::getAccountRootIndex (txn.getSourceAccount ()));
if (!txnAcct)
terResult = terNO_ACCOUNT;
@@ -177,16 +186,21 @@ TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, Trans
{
if (!checkInvariants (terResult, txn, params))
{
WriteLog (lsFATAL, TransactionEngine) << "Transaction violates invariants";
WriteLog (lsFATAL, TransactionEngine) << txn.getJson (0);
WriteLog (lsFATAL, TransactionEngine) << transToken (terResult) << ": " << transHuman (terResult);
WriteLog (lsFATAL, TransactionEngine) << mNodes.getJson (0);
WriteLog (lsFATAL, TransactionEngine) <<
"Transaction violates invariants";
WriteLog (lsFATAL, TransactionEngine) <<
txn.getJson (0);
WriteLog (lsFATAL, TransactionEngine) <<
transToken (terResult) << ": " << transHuman (terResult);
WriteLog (lsFATAL, TransactionEngine) <<
mNodes.getJson (0);
didApply = false;
terResult = tefINTERNAL;
}
else
{
// Transaction succeeded fully or (retries are not allowed and the transaction could claim a fee)
// Transaction succeeded fully or (retries are not allowed and the
// transaction could claim a fee)
Serializer m;
mNodes.calcRawMeta (m, terResult, mTxnSeq++);
@@ -199,7 +213,8 @@ TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, Trans
{
if (!mLedger->addTransaction (txID, s))
{
WriteLog (lsFATAL, TransactionEngine) << "Tried to add transaction to open ledger that already had it";
WriteLog (lsFATAL, TransactionEngine) <<
"Tried to add transaction to open ledger that already had it";
assert (false);
throw std::runtime_error ("Duplicate transaction applied");
}
@@ -208,7 +223,8 @@ TER TransactionEngine::applyTransaction (const SerializedTransaction& txn, Trans
{
if (!mLedger->addTransaction (txID, s, m))
{
WriteLog (lsFATAL, TransactionEngine) << "Tried to add transaction to ledger that already had it";
WriteLog (lsFATAL, TransactionEngine) <<
"Tried to add transaction to ledger that already had it";
assert (false);
throw std::runtime_error ("Duplicate transaction applied to closed ledger");
}