Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into action-wip
Browse files Browse the repository at this point in the history
* upstream/develop:
  Set version to 2.1.0-rc1
  `fixInnerObjTemplate`: set inner object template (4906)
  feat: allow `port_grpc` to be specified in `[server]` stanza (4728)
  build: add headers needed in Conan package for libxrpl (4885)
  `fixNFTokenReserve`: ensure NFT tx fails when reserve is not met (4767)
  fix(libxrpl): change library names in Conan recipe (4831)
  test: check for success/failure of Windows CI unit tests (4871)
  test: add unit test for redundant payment (4860)
  • Loading branch information
ximinez committed Feb 8, 2024
2 parents f1a3f38 + da68651 commit e296805
Show file tree
Hide file tree
Showing 30 changed files with 888 additions and 128 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,7 @@ jobs:
configuration: ${{ matrix.configuration }}
cmake-args: '${{ matrix.cmake-args }}'
cmake-target: install
- name: test (permitted to silently fail)
- name: test
shell: bash
# Github runners are resource limited, which causes unit tests to fail
# (e.g. OOM). To allow forward progress until self-hosted runners are
# up and running reliably, allow the job to succeed even if tests fail.
continue-on-error: true
run: |
${build_dir}/${{ matrix.configuration }}/rippled --unittest --unittest-jobs $(nproc)
36 changes: 35 additions & 1 deletion Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,11 @@ install (
FILES
src/ripple/json/impl/json_assert.h
DESTINATION include/ripple/json/impl)

install (
FILES
src/ripple/net/RPCErr.h
DESTINATION include/ripple/net)
install (
FILES
src/ripple/protocol/AccountID.h
Expand Down Expand Up @@ -302,7 +307,35 @@ install (
src/ripple/protocol/impl/STVar.h
src/ripple/protocol/impl/secp256k1.h
DESTINATION include/ripple/protocol/impl)

install (
FILES
src/ripple/resource/Fees.h
src/ripple/resource/Charge.h
DESTINATION include/ripple/resource)
install (
FILES
src/ripple/server/Port.h
src/ripple/server/Server.h
src/ripple/server/Session.h
src/ripple/server/SimpleWriter.h
src/ripple/server/Writer.h
src/ripple/server/WSSession.h
src/ripple/server/Handoff.h
DESTINATION include/ripple/server)
install (
FILES
src/ripple/server/impl/ServerImpl.h
src/ripple/server/impl/io_list.h
src/ripple/server/impl/Door.h
src/ripple/server/impl/PlainHTTPPeer.h
src/ripple/server/impl/PlainWSPeer.h
src/ripple/server/impl/BaseHTTPPeer.h
src/ripple/server/impl/BaseWSPeer.h
src/ripple/server/impl/BasePeer.h
src/ripple/server/impl/LowestLayer.h
src/ripple/server/impl/SSLHTTPPeer.h
src/ripple/server/impl/SSLWSPeer.h
DESTINATION include/ripple/server/impl)
#[===================================[
beast/legacy headers installation
#]===================================]
Expand Down Expand Up @@ -369,6 +402,7 @@ install (
src/ripple/beast/utility/PropertyStream.h
src/ripple/beast/utility/Zero.h
src/ripple/beast/utility/rngfill.h
src/ripple/beast/utility/WrappedSink.h
DESTINATION include/ripple/beast/utility)
# WARNING!! -- horrible levelization ahead
# (these files should be isolated or moved...but
Expand Down
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
7 changes: 4 additions & 3 deletions src/ripple/app/main/GRPCServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <ripple/resource/Fees.h>

#include <ripple/beast/net/IPAddressConversion.h>
#include <ripple/core/ConfigSections.h>

namespace ripple {

Expand Down Expand Up @@ -427,9 +428,9 @@ GRPCServerImpl::GRPCServerImpl(Application& app)
: app_(app), journal_(app_.journal("gRPC Server"))
{
// if present, get endpoint from config
if (app_.config().exists("port_grpc"))
if (app_.config().exists(SECTION_PORT_GRPC))
{
const auto& section = app_.config().section("port_grpc");
Section const& section = app_.config().section(SECTION_PORT_GRPC);

auto const optIp = section.get("ip");
if (!optIp)
Expand Down Expand Up @@ -659,7 +660,7 @@ GRPCServerImpl::setupListeners()
secureGatewayIPs_));
}
return requests;
};
}

bool
GRPCServerImpl::start()
Expand Down
4 changes: 2 additions & 2 deletions src/ripple/app/misc/NetworkOPs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2719,9 +2719,9 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
}
}

if (app_.config().exists("port_grpc"))
if (app_.config().exists(SECTION_PORT_GRPC))
{
auto const& grpcSection = app_.config().section("port_grpc");
auto const& grpcSection = app_.config().section(SECTION_PORT_GRPC);
auto const optPort = grpcSection.get("port");
if (optPort && grpcSection.get("ip"))
{
Expand Down
16 changes: 14 additions & 2 deletions src/ripple/app/misc/impl/AMMUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ std::uint16_t
getTradingFee(ReadView const& view, SLE const& ammSle, AccountID const& account)
{
using namespace std::chrono;
assert(
!view.rules().enabled(fixInnerObjTemplate) ||
ammSle.isFieldPresent(sfAuctionSlot));
if (ammSle.isFieldPresent(sfAuctionSlot))
{
auto const& auctionSlot =
Expand Down Expand Up @@ -287,17 +290,26 @@ initializeFeeAuctionVote(
Issue const& lptIssue,
std::uint16_t tfee)
{
auto const& rules = view.rules();
// AMM creator gets the voting slot.
STArray voteSlots;
STObject voteEntry{sfVoteEntry};
STObject voteEntry = STObject::makeInnerObject(sfVoteEntry, rules);
if (tfee != 0)
voteEntry.setFieldU16(sfTradingFee, tfee);
voteEntry.setFieldU32(sfVoteWeight, VOTE_WEIGHT_SCALE_FACTOR);
voteEntry.setAccountID(sfAccount, account);
voteSlots.push_back(voteEntry);
ammSle->setFieldArray(sfVoteSlots, voteSlots);
// AMM creator gets the auction slot for free.
auto& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
// AuctionSlot is created on AMMCreate and updated on AMMDeposit
// when AMM is in an empty state
if (rules.enabled(fixInnerObjTemplate) &&
!ammSle->isFieldPresent(sfAuctionSlot))
{
STObject auctionSlot = STObject::makeInnerObject(sfAuctionSlot, rules);
ammSle->set(std::move(auctionSlot));
}
STObject& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
auctionSlot.setAccountID(sfAccount, account);
// current + sec in 24h
auto const expiration = std::chrono::duration_cast<std::chrono::seconds>(
Expand Down
14 changes: 12 additions & 2 deletions src/ripple/app/tx/impl/AMMBid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,18 @@ applyBid(
return {tecINTERNAL, false};
STAmount const lptAMMBalance = (*ammSle)[sfLPTokenBalance];
auto const lpTokens = ammLPHolds(sb, *ammSle, account_, ctx_.journal);
if (!ammSle->isFieldPresent(sfAuctionSlot))
ammSle->makeFieldPresent(sfAuctionSlot);
auto const& rules = ctx_.view().rules();
if (!rules.enabled(fixInnerObjTemplate))
{
if (!ammSle->isFieldPresent(sfAuctionSlot))
ammSle->makeFieldPresent(sfAuctionSlot);
}
else
{
assert(ammSle->isFieldPresent(sfAuctionSlot));
if (!ammSle->isFieldPresent(sfAuctionSlot))
return {tecINTERNAL, false};
}
auto& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
auto const current =
duration_cast<seconds>(
Expand Down
9 changes: 7 additions & 2 deletions src/ripple/app/tx/impl/AMMVote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ applyVote(
Number den{0};
// Account already has vote entry
bool foundAccount = false;
auto const& rules = ctx_.view().rules();
// Iterate over the current vote entries and update each entry
// per current total tokens balance and each LP tokens balance.
// Find the entry with the least tokens and whether the account
Expand All @@ -119,7 +120,7 @@ applyVote(
continue;
}
auto feeVal = entry[sfTradingFee];
STObject newEntry{sfVoteEntry};
STObject newEntry = STObject::makeInnerObject(sfVoteEntry, rules);
// The account already has the vote entry.
if (account == account_)
{
Expand Down Expand Up @@ -158,7 +159,7 @@ applyVote(
{
auto update = [&](std::optional<std::uint8_t> const& minPos =
std::nullopt) {
STObject newEntry{sfVoteEntry};
STObject newEntry = STObject::makeInnerObject(sfVoteEntry, rules);
if (feeNew != 0)
newEntry.setFieldU16(sfTradingFee, feeNew);
newEntry.setFieldU32(
Expand Down Expand Up @@ -199,6 +200,10 @@ applyVote(
}
}

assert(
!ctx_.view().rules().enabled(fixInnerObjTemplate) ||
ammSle->isFieldPresent(sfAuctionSlot));

// Update the vote entries and the trading/discounted fee.
ammSle->setFieldArray(sfVoteSlots, updatedVoteSlots);
if (auto const fee = static_cast<std::int64_t>(num / den))
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
13 changes: 7 additions & 6 deletions src/ripple/core/ConfigSections.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct ConfigSection
// VFALCO TODO Rename and replace these macros with variables.
#define SECTION_AMENDMENTS "amendments"
#define SECTION_AMENDMENT_MAJORITY_TIME "amendment_majority_time"
#define SECTION_BETA_RPC_API "beta_rpc_api"
#define SECTION_CLUSTER_NODES "cluster_nodes"
#define SECTION_COMPRESSION "compression"
#define SECTION_DEBUG_LOGFILE "debug_logfile"
Expand All @@ -57,10 +58,13 @@ struct ConfigSection
#define SECTION_FETCH_DEPTH "fetch_depth"
#define SECTION_HISTORICAL_SHARD_PATHS "historical_shard_paths"
#define SECTION_INSIGHT "insight"
#define SECTION_IO_WORKERS "io_workers"
#define SECTION_IPS "ips"
#define SECTION_IPS_FIXED "ips_fixed"
#define SECTION_LEDGER_HISTORY "ledger_history"
#define SECTION_LEDGER_REPLAY "ledger_replay"
#define SECTION_MAX_TRANSACTIONS "max_transactions"
#define SECTION_NETWORK_ID "network_id"
#define SECTION_NETWORK_QUORUM "network_quorum"
#define SECTION_NODE_SEED "node_seed"
#define SECTION_NODE_SIZE "node_size"
Expand All @@ -73,6 +77,8 @@ struct ConfigSection
#define SECTION_PEERS_MAX "peers_max"
#define SECTION_PEERS_IN_MAX "peers_in_max"
#define SECTION_PEERS_OUT_MAX "peers_out_max"
#define SECTION_PORT_GRPC "port_grpc"
#define SECTION_PREFETCH_WORKERS "prefetch_workers"
#define SECTION_REDUCE_RELAY "reduce_relay"
#define SECTION_RELATIONAL_DB "relational_db"
#define SECTION_RELAY_PROPOSALS "relay_proposals"
Expand All @@ -84,6 +90,7 @@ struct ConfigSection
#define SECTION_SSL_VERIFY_FILE "ssl_verify_file"
#define SECTION_SSL_VERIFY_DIR "ssl_verify_dir"
#define SECTION_SERVER_DOMAIN "server_domain"
#define SECTION_SWEEP_INTERVAL "sweep_interval"
#define SECTION_VALIDATORS_FILE "validators_file"
#define SECTION_VALIDATION_SEED "validation_seed"
#define SECTION_VALIDATOR_KEYS "validator_keys"
Expand All @@ -94,12 +101,6 @@ struct ConfigSection
#define SECTION_VALIDATOR_TOKEN "validator_token"
#define SECTION_VETO_AMENDMENTS "veto_amendments"
#define SECTION_WORKERS "workers"
#define SECTION_IO_WORKERS "io_workers"
#define SECTION_PREFETCH_WORKERS "prefetch_workers"
#define SECTION_LEDGER_REPLAY "ledger_replay"
#define SECTION_BETA_RPC_API "beta_rpc_api"
#define SECTION_SWEEP_INTERVAL "sweep_interval"
#define SECTION_NETWORK_ID "network_id"

} // namespace ripple

Expand Down
Loading

0 comments on commit e296805

Please sign in to comment.