Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single Asset Vault #5224

Open
wants to merge 69 commits into
base: develop
Choose a base branch
from
Open

Single Asset Vault #5224

wants to merge 69 commits into from

Conversation

Bronek
Copy link
Collaborator

@Bronek Bronek commented Dec 17, 2024

High Level Overview of Change

This is implementation of XLS-65 Single Asset Vault. First draft was implemented by @thejohnfreeman in #5147

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Performance (increase or change in throughput and/or latency)
  • Tests (you added tests for code that already exists, or your new feature included in this PR)
  • Documentation update
  • Chore (no impact to binary, e.g. .gitignore, formatting, dropping support for older tooling)
  • Release

API Impact

  • Public API: New feature (new methods and/or new fields)
  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)
  • libxrpl change (any change that may affect libxrpl or dependents of libxrpl)
  • Peer protocol change (must be backward compatible or bump the peer protocol version)

Copy link
Collaborator

@gregtatcam gregtatcam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got compile error on MAC M1 Sequoia 15.1.1, apple clang 16.0.0

xrpl/json/json_value.h:705:5: error: constexpr function's return type 'Value' is not a literal type
705 |     operator()(T&& t) const
xrpl/json/json_value.h:148:7: note: 'Value' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors
148 | class Value

Copy link
Collaborator

@gregtatcam gregtatcam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few warnings, of which the most common is:

xrpl/protocol/STIssue.h:49:5: warning: definition of implicit copy constructor for 'STIssue' is deprecated because it has a user-declared copy assignment operator [-Wdeprecated-copy]
   49 |     operator=(STIssue const& rhs) = default; 

And once the compile error is fixed (remove constexpr in to_json_fn::operator() return value), there are VaultDelete unit-tests failures.

@Bronek
Copy link
Collaborator Author

Bronek commented Dec 18, 2024

There are a few warnings, of which the most common is:

xrpl/protocol/STIssue.h:49:5: warning: definition of implicit copy constructor for 'STIssue' is deprecated because it has a user-declared copy assignment operator [-Wdeprecated-copy]
   49 |     operator=(STIssue const& rhs) = default; 

And once the compile error is fixed (remove constexpr in to_json_fn::operator() return value), there are VaultDelete unit-tests failures.

This is fixed now. The VaultDelete still needs to be fixed, but for the time being I've commented the failing test out. Compilation errors in clang 16 fixed, also simplified json_value.h a little.

@Bronek Bronek force-pushed the vault branch 3 times, most recently from 2bcc6ad to 17af6e7 Compare December 18, 2024 17:23
Copy link

codecov bot commented Dec 18, 2024

Codecov Report

Attention: Patch coverage is 72.72727% with 240 lines in your changes missing coverage. Please review.

Project coverage is 78.0%. Comparing base (2216e5a) to head (1441c91).

Files with missing lines Patch % Lines
src/xrpld/ledger/detail/View.cpp 64.2% 76 Missing ⚠️
src/xrpld/app/misc/CredentialHelpers.cpp 20.4% 43 Missing ⚠️
src/xrpld/app/tx/detail/VaultCreate.cpp 77.8% 22 Missing ⚠️
src/xrpld/app/tx/detail/VaultDeposit.cpp 75.0% 19 Missing ⚠️
src/xrpld/app/tx/detail/VaultWithdraw.cpp 73.3% 16 Missing ⚠️
src/xrpld/app/tx/detail/VaultClawback.cpp 81.7% 15 Missing ⚠️
src/xrpld/app/tx/detail/VaultSet.cpp 79.2% 10 Missing ⚠️
src/xrpld/app/tx/detail/VaultDelete.cpp 80.0% 9 Missing ⚠️
src/libxrpl/protocol/STNumber.cpp 77.1% 8 Missing ⚠️
src/xrpld/app/tx/detail/MPTokenAuthorize.cpp 78.9% 4 Missing ⚠️
... and 6 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           develop   #5224     +/-   ##
=========================================
- Coverage     78.1%   78.0%   -0.1%     
=========================================
  Files          790     802     +12     
  Lines        67908   68648    +740     
  Branches      8230    8334    +104     
=========================================
+ Hits         53034   53541    +507     
- Misses       14874   15107    +233     
Files with missing lines Coverage Δ
include/xrpl/json/json_value.h 98.5% <ø> (ø)
include/xrpl/protocol/AMMCore.h 100.0% <ø> (ø)
include/xrpl/protocol/Asset.h 95.5% <100.0%> (+0.7%) ⬆️
include/xrpl/protocol/Feature.h 100.0% <ø> (ø)
include/xrpl/protocol/IOUAmount.h 100.0% <ø> (ø)
include/xrpl/protocol/Indexes.h 100.0% <100.0%> (ø)
include/xrpl/protocol/MPTAmount.h 100.0% <ø> (ø)
include/xrpl/protocol/MPTIssue.h 100.0% <100.0%> (ø)
include/xrpl/protocol/SField.h 100.0% <ø> (ø)
include/xrpl/protocol/STAmount.h 95.5% <100.0%> (+0.3%) ⬆️
... and 47 more

... and 10 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ckeshava
Copy link
Collaborator

Hello, I'm unable to build the tip of this branch. I see this error message:

====================[ Build | rippled | Debug ]=================================
/Applications/CLion.app/Contents/bin/cmake/mac/aarch64/bin/cmake --build /Users/ckeshavabs/rippled/cmake-build-debug --target rippled -j 8
[0/2] Re-checking globbed directories...
[17/199] Building CXX object CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o
FAILED: CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DBOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS -DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT -DBOOST_BEAST_ALLOW_DEPRECATED -DBOOST_CONTAINER_FWD_BAD_DEQUE -DBOOST_COROUTINES_NO_DEPRECATION_WARNING -DBOOST_FILESYSTEM_DEPRECATED -DBOOST_STACKTRACE_ADDR2LINE_LOCATION=\"/usr/bin/addr2line\" -DBOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED -DBOOST_STACKTRACE_USE_ADDR2LINE -DBOOST_STACKTRACE_USE_BACKTRACE -DBOOST_STACKTRACE_USE_NOOP -DCARES_STATICLIB -DDATE_HEADER_ONLY -DDEBUG -DENABLE_TESTS -DGIT_BRANCH=\"HEAD\" -DGIT_COMMIT_HASH=\"04503c9fa4ce1582946c8875e832ed26d5ddb4a5\" -DHAS_UNCAUGHT_EXCEPTIONS=1 -DOPENSSL_NO_SSL2 -DRIPPLE_ROCKSDB_AVAILABLE=1 -D_DEBUG -I/Users/ckeshavabs/rippled/src -I/Users/ckeshavabs/rippled/external/ed25519-donna -I/Users/ckeshavabs/rippled/external/secp256k1/include -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.basics -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.beast -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.crypto -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.json -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.resource -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.server -isystem /Users/ckeshavabs/.conan/data/boost/1.82.0/_/_/package/a69d410abc9222719bf488aebe7f988537c9471e/include -isystem /Users/ckeshavabs/.conan/data/rocksdb/6.29.5/_/_/package/46267c207aae043922202e85b9966ee76a1a2185/include -isystem /Users/ckeshavabs/.conan/data/snappy/1.1.10/_/_/package/a898b5d7c2f3bb5cde3b7f2d5435af986f98fcce/include -isystem /Users/ckeshavabs/.conan/data/lz4/1.9.3/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/openssl/1.1.1u/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/soci/4.0.3/_/_/package/0a60a410fb97961de9d8237fbf765e52ad14ee1e/include -isystem /Users/ckeshavabs/.conan/data/libiconv/1.17/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/bzip2/1.0.8/_/_/package/13ca22f8effcf3ca9f2df5e5d806439a1cf178d2/include -isystem /Users/ckeshavabs/.conan/data/zlib/1.2.13/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/libbacktrace/cci.20210118/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/sqlite3/3.42.0/_/_/package/d9b7a5bc640f087bac717436397686a06b511bba/include -isystem /Users/ckeshavabs/.conan/data/nudb/2.0.8/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include -isystem /Users/ckeshavabs/.conan/data/libarchive/3.6.2/_/_/package/533bc0d623a9fb71a5227f487ee9b08b1bd76d7c/include -isystem /Users/ckeshavabs/.conan/data/abseil/20230125.3/_/_/package/a898b5d7c2f3bb5cde3b7f2d5435af986f98fcce/include -isystem /Users/ckeshavabs/.conan/data/date/3.0.1/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include -isystem /Users/ckeshavabs/rippled/cmake-build-debug/pb-xrpl.libpb -isystem /Users/ckeshavabs/rippled/cmake-build-debug/pb-xrpl.libpb/xrpl/proto -isystem /Users/ckeshavabs/.conan/data/protobuf/3.21.9/_/_/package/f270d4cd7588a421e0318c663180bba71356232c/include -isystem /Users/ckeshavabs/.conan/data/grpc/1.50.1/_/_/package/3c189434ebcd9ca7527392a458bd24a1cd892fea/include -isystem /Users/ckeshavabs/.conan/data/c-ares/1.19.1/_/_/package/f4cac816079be8729ac36dbfaf1ee519e2852a98/include -isystem /Users/ckeshavabs/.conan/data/re2/20230301/_/_/package/a898b5d7c2f3bb5cde3b7f2d5435af986f98fcce/include -isystem /Users/ckeshavabs/.conan/data/xxhash/0.8.2/_/_/package/695d70e32c88f399cf892ed745d51834f44f78e3/include -stdlib=libc++ -DBOOST_ASIO_DISABLE_CONCEPTS -Wall -Wdeprecated -Wextra -Wno-unused-parameter -g -std=c++20 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -fPIE -fcolor-diagnostics -frtti -Wnon-virtual-dtor -Wno-sign-compare -Wno-char-subscripts -Wno-format -Wno-unused-local-typedefs -fstack-protector -MD -MT CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o -MF CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o.d -o CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o -c /Users/ckeshavabs/rippled/src/test/app/Vault_test.cpp
/Users/ckeshavabs/rippled/src/test/app/Vault_test.cpp:68:26: error: call to constructor of 'STAmount' is ambiguous
   68 |                          STAmount(asset.raw(), 1ul, 0, true), "")});
      |                          ^        ~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol/xrpl/protocol/STAmount.h:129:5: note: candidate constructor [with A = ripple::Asset]
  129 |     STAmount(
      |     ^
/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol/xrpl/protocol/STAmount.h:378:11: note: candidate constructor [with A = ripple::Asset]
  378 | STAmount::STAmount(
      |           ^
/Users/ckeshavabs/rippled/src/test/app/Vault_test.cpp:148:26: error: call to constructor of 'STAmount' is ambiguous
  148 |                          STAmount(asset.raw(), 1ul, 0, true), "")});
      |                          ^        ~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol/xrpl/protocol/STAmount.h:129:5: note: candidate constructor [with A = ripple::Asset]
  129 |     STAmount(
      |     ^
/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol/xrpl/protocol/STAmount.h:378:11: note: candidate constructor [with A = ripple::Asset]
  378 | STAmount::STAmount(
      |           ^
/Users/ckeshavabs/rippled/src/test/app/Vault_test.cpp:197:26: error: call to constructor of 'STAmount' is ambiguous
  197 |                          STAmount(asset.raw(), 1ul, 0, true), "")});
      |                          ^        ~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol/xrpl/protocol/STAmount.h:129:5: note: candidate constructor [with A = ripple::Asset]
  129 |     STAmount(
      |     ^
/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol/xrpl/protocol/STAmount.h:378:11: note: candidate constructor [with A = ripple::Asset]
  378 | STAmount::STAmount(
      |           ^
3 errors generated.
[24/199] Building CXX object CMakeFiles/rippled.dir/src/test/beast/aged_associative_container_test.cpp.o
ninja: build stopped: subcommand failed.

This is my environment configuration:

➜  rippled git:(04503c9fa4) ✗ uname -a
Darwin ckeshavabs-37XPH-MBP 24.2.0 Darwin Kernel Version 24.2.0: Fri Dec  6 19:01:59 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T6000 arm64
➜  rippled git:(04503c9fa4) ✗ clang --version
Apple clang version 16.0.0 (clang-1600.0.26.6)
Target: arm64-apple-darwin24.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

@ckeshava
Copy link
Collaborator

Perhaps, you meant to do this: Bronek#4 ?

// No `LossUnrealized`.
view().insert(vault);

return tesSUCCESS;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the successful execution of VaultCreate transaction, how can I fetch the ledger-object index? Are there any helpful fields in the transaction's meta-data?

I can iterate through all Vault-type objects in the response of AccountObjects RPC. If I want to use the LedgerEntry RPC, how can I get the ledger-index of the Vault object?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This problem is also highlighted by this test utility method: https://github.com/Bronek/rippled/blob/04503c9fa4ce1582946c8875e832ed26d5ddb4a5/src/test/jtx/impl/vault.cpp#L36

Are users expected to calculate the vault_id by themselves?

Copy link
Collaborator Author

@Bronek Bronek Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be returned in metadata as LedgerIndex of the newly created Vault object, like e.g. here

"CreatedNode" :
{
  "LedgerEntryType" : "Vault",
  "LedgerIndex" : "C043BB1B350FFC5FED21E40535609D3D95BC0E3CE252E2F69F85BE0157020A52",
  "NewFields" :
  { . . .

I will add unit test to verify the metadata returned from VaultCreate

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This problem is also highlighted by this test utility method: https://github.com/Bronek/rippled/blob/04503c9fa4ce1582946c8875e832ed26d5ddb4a5/src/test/jtx/impl/vault.cpp#L36

Are users expected to calculate the vault_id by themselves?

The sdks must have the ability to generate ALL hashes/indexes because in a batch transaction, you will not have the response. So yes, the user will need to be able to generate this from whatever fields are required to create the index.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Vault ID can be pre-generated by the user, it is a Sha512-half of the Vault space key, the account ID creating the vault, and the sequence number of the transaction creating the vault. https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0065d-single-asset-vault#211-object-identifier

{sfDestination, soeOPTIONAL},
}))

/** This transaction trades shares for assets with a vault. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this comment needs to be modified

TRANSACTION(ttVAULT_CLAWBACK, 69, VaultClawback, ({
{sfVaultID, soeREQUIRED},
{sfHolder, soeREQUIRED},
{sfAmount, soeDEFAULT, soeMPTSupported},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I do not specify the sfAmount field in the VaultClawback transaction, I get a tecWRONG_ASSET error from this code: https://github.com/Bronek/rippled/blob/04503c9fa4ce1582946c8875e832ed26d5ddb4a5/src/xrpld/app/tx/detail/VaultClawback.cpp#L66

Does the user have the option of not specifying the Amount field? How is the default value determined?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I observed this behavior with IOUs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point - I checked the spec and indeed we do allow Amount to be unspecified, in which case I should default to 0 which will clawback all the funds. I will fix it now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohhh I see how this works.

@mvadari I need your help here; basically we have {sfAmount, soeDEFAULT, soeMPTSupported}, in the body of ttVAULT_CLAWBACK which means that, when not specified, we get all zeroes. The amount is not just a number, it is also an asset. When we get all zeroes as an asset I guess that means XRP or whatever, which clearly is not the asset being traded in the vault, hence this block fails

    STAmount const amount = ctx.tx[sfAmount];
    if (asset != amount.asset())
        return tecWRONG_ASSET;

The problem here is that, had the users explicitly specified all zeroes (number and asset, and again I guess that would be XRP) we would have no way of knowing that it was manually selected by the user rather than auto-populated by the soeDEFAULT behaviour.

I guess in this case I need to switch from soeDEFAULT to soeOPTIONAL (and then refer to this field as tx[~sfAmount]) ? If so, do I also need soeMPTSupported or not ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I did as discussed above (switched to soeOPTIONAL and adjusted references to tx[~sfAmount] as needed

Copy link
Collaborator

@mvadari mvadari Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess in this case I need to switch from soeDEFAULT to soeOPTIONAL (and then refer to this field as tx[~sfAmount]) ?

That sounds right.

If so, do I also need soeMPTSupported or not ?

Is an MPT a valid value for sfAmount here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is an MPT a valid value for sfAmount here?

Yes, asset can be IOU or MPT.

std::size_t constexpr maxVaultDataLength = 256;

/** Vault withdrawal policies */
std::uint8_t constexpr vaultStrategyFirstComeFirstServe = 1;
Copy link
Collaborator

@vlntb vlntb Mar 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to XLS-0065d-single-asset-vault specification this field should be called strFirstComeFirstServe .

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name in spec is potentially misleading. Also it is internal, hence it does not affect the protocol in anyway.

if (issuance->getFlags() & lsfMPTLocked)
return tecLOCKED;
if ((issuance->getFlags() & lsfMPTCanTransfer) == 0)
return tecLOCKED;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TEC code for lsfMPTCanTransfer should be the asset is not transferable, instead of asset is locked.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kind-of. The return code from canTransfer , as used and reported e.g. in Payment::doApply is tecNO_AUTH. I will switch to this one. We do not have "asset is not transferable" error and adding it now would cause inconsistency with Payment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is now changed to tecNO_AUTH

}

TER
VaultCreate::doApply()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the spec:

If Vault.Asset is an IOU:
Create a RippleState object between the pseudo-account AccountRoot and Issuer AccountRoot.

If Vault.Asset is an MPT:
Create MPToken object for the pseudo-account for the Asset.MPTokenIssuance.

At the moment only MPT is supported.

Copy link
Collaborator Author

@Bronek Bronek Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you confused MPTokenIssuanceCreate::create (which creates MPTokenIssuance to hold the shares of the vault) with addEmptyHolding (which creates either RippleState or MPToken for the assets held in the vault, as per spec)

Look for addEmptyHolding in View.cpp


// A deposit must not push the vault over its limit.
auto const maximum = *vault->at(sfAssetMaximum);
if (maximum != 0 && *vault->at(sfAssetTotal) > maximum)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this check be done before vault assets are incremented (Lines 154...155)?
Otherwise, we push vault over its limits and then check this condition afterwards.

@Bronek
Copy link
Collaborator Author

Bronek commented Mar 6, 2025

Hello, I'm unable to build the tip of this branch. I see this error message:

====================[ Build | rippled | Debug ]=================================
/Applications/CLion.app/Contents/bin/cmake/mac/aarch64/bin/cmake --build /Users/ckeshavabs/rippled/cmake-build-debug --target rippled -j 8
[0/2] Re-checking globbed directories...
[17/199] Building CXX object CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o
FAILED: CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DBOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS -DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT -DBOOST_BEAST_ALLOW_DEPRECATED -DBOOST_CONTAINER_FWD_BAD_DEQUE -DBOOST_COROUTINES_NO_DEPRECATION_WARNING -DBOOST_FILESYSTEM_DEPRECATED -DBOOST_STACKTRACE_ADDR2LINE_LOCATION=\"/usr/bin/addr2line\" -DBOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED -DBOOST_STACKTRACE_USE_ADDR2LINE -DBOOST_STACKTRACE_USE_BACKTRACE -DBOOST_STACKTRACE_USE_NOOP -DCARES_STATICLIB -DDATE_HEADER_ONLY -DDEBUG -DENABLE_TESTS -DGIT_BRANCH=\"HEAD\" -DGIT_COMMIT_HASH=\"04503c9fa4ce1582946c8875e832ed26d5ddb4a5\" -DHAS_UNCAUGHT_EXCEPTIONS=1 -DOPENSSL_NO_SSL2 -DRIPPLE_ROCKSDB_AVAILABLE=1 -D_DEBUG -I/Users/ckeshavabs/rippled/src -I/Users/ckeshavabs/rippled/external/ed25519-donna -I/Users/ckeshavabs/rippled/external/secp256k1/include -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.basics -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.beast -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.crypto -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.json -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.protocol -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.resource -I/Users/ckeshavabs/rippled/cmake-build-debug/modules/xrpl.libxrpl.server -isystem /Users/ckeshavabs/.conan/data/boost/1.82.0/_/_/package/a69d410abc9222719bf488aebe7f988537c9471e/include -isystem /Users/ckeshavabs/.conan/data/rocksdb/6.29.5/_/_/package/46267c207aae043922202e85b9966ee76a1a2185/include -isystem /Users/ckeshavabs/.conan/data/snappy/1.1.10/_/_/package/a898b5d7c2f3bb5cde3b7f2d5435af986f98fcce/include -isystem /Users/ckeshavabs/.conan/data/lz4/1.9.3/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/openssl/1.1.1u/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/soci/4.0.3/_/_/package/0a60a410fb97961de9d8237fbf765e52ad14ee1e/include -isystem /Users/ckeshavabs/.conan/data/libiconv/1.17/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/bzip2/1.0.8/_/_/package/13ca22f8effcf3ca9f2df5e5d806439a1cf178d2/include -isystem /Users/ckeshavabs/.conan/data/zlib/1.2.13/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/libbacktrace/cci.20210118/_/_/package/618dbd84aadeba766a763e0b591cd691ef45e97b/include -isystem /Users/ckeshavabs/.conan/data/sqlite3/3.42.0/_/_/package/d9b7a5bc640f087bac717436397686a06b511bba/include -isystem /Users/ckeshavabs/.conan/data/nudb/2.0.8/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include -isystem /Users/ckeshavabs/.conan/data/libarchive/3.6.2/_/_/package/533bc0d623a9fb71a5227f487ee9b08b1bd76d7c/include -isystem /Users/ckeshavabs/.conan/data/abseil/20230125.3/_/_/package/a898b5d7c2f3bb5cde3b7f2d5435af986f98fcce/include -isystem /Users/ckeshavabs/.conan/data/date/3.0.1/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include -isystem /Users/ckeshavabs/rippled/cmake-build-debug/pb-xrpl.libpb -isystem /Users/ckeshavabs/rippled/cmake-build-debug/pb-xrpl.libpb/xrpl/proto -isystem /Users/ckeshavabs/.conan/data/protobuf/3.21.9/_/_/package/f270d4cd7588a421e0318c663180bba71356232c/include -isystem /Users/ckeshavabs/.conan/data/grpc/1.50.1/_/_/package/3c189434ebcd9ca7527392a458bd24a1cd892fea/include -isystem /Users/ckeshavabs/.conan/data/c-ares/1.19.1/_/_/package/f4cac816079be8729ac36dbfaf1ee519e2852a98/include -isystem /Users/ckeshavabs/.conan/data/re2/20230301/_/_/package/a898b5d7c2f3bb5cde3b7f2d5435af986f98fcce/include -isystem /Users/ckeshavabs/.conan/data/xxhash/0.8.2/_/_/package/695d70e32c88f399cf892ed745d51834f44f78e3/include -stdlib=libc++ -DBOOST_ASIO_DISABLE_CONCEPTS -Wall -Wdeprecated -Wextra -Wno-unused-parameter -g -std=c++20 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -fPIE -fcolor-diagnostics -frtti -Wnon-virtual-dtor -Wno-sign-compare -Wno-char-subscripts -Wno-format -Wno-unused-local-typedefs -fstack-protector -MD -MT CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o -MF CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o.d -o CMakeFiles/rippled.dir/src/test/app/Vault_test.cpp.o -c /Users/ckeshavabs/rippled/src/test/app/Vault_test.cpp
/Users/ckeshavabs/rippled/src/test/app/Vault_test.cpp:68:26: error: call to constructor of 'STAmount' is ambiguous
   68 |                          STAmount(asset.raw(), 1ul, 0, true), "")});
      |                          ^        ~~~~~~~~~~~~~~~~~~~~~~~~~
. . .

This should be now fixed (thanks @vlntb)

}

[[nodiscard]] TER
enforceMPTokenAuthorization(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function to be used anywhere that one needs to check if a MPToken is authorized? Or is this only used by Vault?

I do a similar check in escrow, I will do a similar one in paychan.

Copy link
Collaborator

@dangell7 dangell7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

partial. just suggestions.

Adding functions to the View that will only be used by one Transactor isn't a good approach imo and if you intend for them to be used agnostically then you shouldn't assume the guards (frozen, auth, canTransfer, global freeze, etc).

I also see A LOT of refactoring, some of which I'm certain will cause a fork. Please, think about if you should do that refactoring here in the PR or another PR.

Also, lol handling permissioned domains in this PR seems like it really increased the complexity, I would think about maybe just implementing this without it, without clawback, so that this PR is easier to review.

You don't have to do any of this, they are just suggestions.

Didn't review Deposit/Set/Withdraw.


// if account has no MPToken, fail
if (!sleToken)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isnt correct imo. If the token does not require authorization, and I dont have the token then technically the response sound be successful. See Escrow and MPTDex. Also notice how this is done for IOU and is there a similar function you are creating for IOU? Also this code here is exactly like requireAuth...

@@ -1088,6 +1223,121 @@ trustDelete(
return tesSUCCESS;
}

[[nodiscard]] TER
addEmptyHolding(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You check frozen in preclaim, and then here you check globalFrozen. This makes this PR really difficult to review. I think keeping it all in one place is better. Also you're checking global freeze way late in the stack, this could be done in preclaim right?

Here is the implementation in Escrow, stolen from Greg and Shawn. Its clean, easy to read, easy to understand. Also if this function will only ever be used by vault then putting it here in View doesn't make sense to me.

escrowCreatePreclaimHelper(

// Note, this is not amendment-gated because we do not want to maintain in
// this file the list of all the amendments which can write to this field.
// Without additional amendments this field is always empty.
auto const maybeDomainID = sleIssuance->at(~sfDomainID);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used by multiple existing functions, therefore unless you gated them all this will cause a fork I believe.

auto const& mptIssue = asset.get<MPTIssue>();
auto const& mptID = mptIssue.getMptID();
// `MPTokenAuthorize::authorize` asserts that the balance is 0.
return MPTokenAuthorize::authorize(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function checks requireAuth for MPT but I don't see you checking that for IOU?

auto asset = ctx.tx[sfAsset];
auto account = ctx.tx[sfAccount];

if (asset.holds<MPTIssue>())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like what Greg and Shawn did with the visit where they separated the checks for IOU vs MPT. Makes it very easy to review. Please think about implementing it. See my comment about EscrowToken for implementation details.

if (txFlags & tfVaultPrivate)
mptFlags |= lsfMPTRequireAuth;

auto maybeShare = MPTokenIssuanceCreate::create(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I'm guessing this isn't finished though because this only handles MPT tokens.


if (auto const domain = ctx.tx[~sfDomainID])
{
if (!ctx.rules.enabled(featurePermissionedDomains))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we checking the permissioned domain ID twice? We already check on lines 39-40 whether the field is present and whether the feature is enabled?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants