Skip to content

Commit

Permalink
Merge commit '828bb64ebc76394cf9a3f7edd42f4588d106932f' into featureN…
Browse files Browse the repository at this point in the history
…FTokenMintOffer
  • Loading branch information
tequdev committed Feb 5, 2024
2 parents 95b2e08 + 828bb64 commit 6ff088e
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 35 deletions.
6 changes: 3 additions & 3 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ def package(self):
def package_info(self):
libxrpl = self.cpp_info.components['libxrpl']
libxrpl.libs = [
'libxrpl_core.a',
'libed25519.a',
'libsecp256k1.a',
'xrpl_core',
'ed25519',
'secp256k1',
]
# TODO: Fix the protobufs to include each other relative to
# `include/`, not `include/ripple/proto/`.
Expand Down
79 changes: 57 additions & 22 deletions src/ripple/app/tx/impl/NFTokenAcceptOffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,60 @@ NFTokenAcceptOffer::pay(
return tesSUCCESS;
}

TER
NFTokenAcceptOffer::transferNFToken(
AccountID const& buyer,
AccountID const& seller,
uint256 const& nftokenID)
{
auto tokenAndPage = nft::findTokenAndPage(view(), seller, nftokenID);

if (!tokenAndPage)
return tecINTERNAL;

if (auto const ret = nft::removeToken(
view(), seller, nftokenID, std::move(tokenAndPage->page));
!isTesSuccess(ret))
return ret;

auto const sleBuyer = view().read(keylet::account(buyer));
if (!sleBuyer)
return tecINTERNAL;

std::uint32_t const buyerOwnerCountBefore =
sleBuyer->getFieldU32(sfOwnerCount);

auto const insertRet =
nft::insertToken(view(), buyer, std::move(tokenAndPage->token));

// if fixNFTokenReserve is enabled, check if the buyer has sufficient
// reserve to own a new object, if their OwnerCount changed.
//
// There was an issue where the buyer accepts a sell offer, the ledger
// didn't check if the buyer has enough reserve, meaning that buyer can get
// NFTs free of reserve.
if (view().rules().enabled(fixNFTokenReserve))
{
// To check if there is sufficient reserve, we cannot use mPriorBalance
// because NFT is sold for a price. So we must use the balance after
// the deduction of the potential offer price. A small caveat here is
// that the balance has already deducted the transaction fee, meaning
// that the reserve requirement is a few drops higher.
auto const buyerBalance = sleBuyer->getFieldAmount(sfBalance);

auto const buyerOwnerCountAfter = sleBuyer->getFieldU32(sfOwnerCount);
if (buyerOwnerCountAfter > buyerOwnerCountBefore)
{
if (auto const reserve =
view().fees().accountReserve(buyerOwnerCountAfter);
buyerBalance < reserve)
return tecINSUFFICIENT_RESERVE;
}
}

return insertRet;
}

TER
NFTokenAcceptOffer::acceptOffer(std::shared_ptr<SLE> const& offer)
{
Expand Down Expand Up @@ -333,17 +387,7 @@ NFTokenAcceptOffer::acceptOffer(std::shared_ptr<SLE> const& offer)
}

// Now transfer the NFT:
auto tokenAndPage = nft::findTokenAndPage(view(), seller, nftokenID);

if (!tokenAndPage)
return tecINTERNAL;

if (auto const ret = nft::removeToken(
view(), seller, nftokenID, std::move(tokenAndPage->page));
!isTesSuccess(ret))
return ret;

return nft::insertToken(view(), buyer, std::move(tokenAndPage->token));
return transferNFToken(buyer, seller, nftokenID);
}

TER
Expand Down Expand Up @@ -431,17 +475,8 @@ NFTokenAcceptOffer::doApply()
return r;
}

auto tokenAndPage = nft::findTokenAndPage(view(), seller, nftokenID);

if (!tokenAndPage)
return tecINTERNAL;

if (auto const ret = nft::removeToken(
view(), seller, nftokenID, std::move(tokenAndPage->page));
!isTesSuccess(ret))
return ret;

return nft::insertToken(view(), buyer, std::move(tokenAndPage->token));
// Now transfer the NFT:
return transferNFToken(buyer, seller, nftokenID);
}

if (bo)
Expand Down
6 changes: 6 additions & 0 deletions src/ripple/app/tx/impl/NFTokenAcceptOffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class NFTokenAcceptOffer : public Transactor
std::shared_ptr<SLE> const& buy,
std::shared_ptr<SLE> const& sell);

TER
transferNFToken(
AccountID const& buyer,
AccountID const& seller,
uint256 const& nfTokenID);

public:
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};

Expand Down
3 changes: 2 additions & 1 deletion src/ripple/protocol/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace detail {
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures = 66;
static constexpr std::size_t numFeatures = 67;

/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated
Expand Down Expand Up @@ -352,6 +352,7 @@ extern uint256 const featureXChainBridge;
extern uint256 const fixDisallowIncomingV1;
extern uint256 const featureDID;
extern uint256 const fixFillOrKill;
extern uint256 const fixNFTokenReserve;
extern uint256 const featureNFTokenMintOffer;

} // namespace ripple
Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/impl/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ REGISTER_FEATURE(XChainBridge, Supported::yes, VoteBehavior::De
REGISTER_FIX (fixDisallowIncomingV1, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FEATURE(DID, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FIX (fixFillOrKill, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FIX (fixNFTokenReserve, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FEATURE(NFTokenMintOffer, Supported::yes, VoteBehavior::DefaultNo);

// The following amendments are obsolete, but must remain supported
Expand Down
13 changes: 10 additions & 3 deletions src/secp256k1/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,16 @@ elseif(APPLE)
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(${PROJECT_NAME}_windows "secp256k1")
if(MSVC)
set(${PROJECT_NAME}_windows "${PROJECT_NAME}")
endif()
# This step is commented out from the original. It is bad practice to change
# the binary base name depending on the platform. CMake already manipulates
# the base name into a final name that fits the conventions of the platform.
# Linkers accept base names on the command line and then look for
# conventional names on disk. This way, developers can use base names
# everywhere (in the CMake and Conan they write) and the tools will do the
# right thing.
# if(MSVC)
# set(${PROJECT_NAME}_windows "${PROJECT_NAME}")
# endif()
set_target_properties(secp256k1 PROPERTIES
ARCHIVE_OUTPUT_NAME "${${PROJECT_NAME}_windows}"
RUNTIME_OUTPUT_NAME "${${PROJECT_NAME}_windows}-${${PROJECT_NAME}_soversion}"
Expand Down
Loading

0 comments on commit 6ff088e

Please sign in to comment.