diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml
index ca351354d43..2aa22bfd776 100644
--- a/.github/workflows/nix.yml
+++ b/.github/workflows/nix.yml
@@ -44,7 +44,7 @@ jobs:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-${{ hashFiles('.github/workflows/nix.yml') }}
- name: install Conan
- run: pip install wheel 'conan>=1.52.0'
+ run: pip install wheel 'conan~=1.52'
- name: check environment
run: |
echo ${PATH} | tr ':' '\n'
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 637eba4ea51..b50f9ab550a 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -46,7 +46,7 @@ jobs:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-${{ hashFiles('.github/workflows/windows.yml') }}
- name: install Conan
- run: pip install wheel 'conan>=1.52.0'
+ run: pip install wheel 'conan~=1.52'
- name: check environment
run: |
$env:PATH -split ';'
diff --git a/Builds/VisualStudio2017/README.md b/Builds/VisualStudio2017/README.md
new file mode 100644
index 00000000000..fce8e824a05
--- /dev/null
+++ b/Builds/VisualStudio2017/README.md
@@ -0,0 +1 @@
+[Build instructions are currently located in `BUILD.md`](../../BUILD.md)
diff --git a/Builds/linux/README.md b/Builds/linux/README.md
index 15a84a33e43..fce8e824a05 100644
--- a/Builds/linux/README.md
+++ b/Builds/linux/README.md
@@ -1,269 +1 @@
-# Linux Build Instructions
-
-This document focuses on building rippled for development purposes under recent
-Ubuntu linux distributions. To build rippled for Redhat, Fedora or Centos
-builds, including docker based builds for those distributions, please consult
-the [rippled-package-builder](https://github.com/ripple/rippled-package-builder)
-repository.
-
-Note: Ubuntu 16.04 users may need to update their compiler (see the dependencies
-section). For non Ubuntu distributions, the steps below should work by
-installing the appropriate dependencies using that distribution's package
-management tools.
-
-
-## Dependencies
-
-gcc-8 or later is required.
-
-Use `apt-get` to install the dependencies provided by the distribution
-
-```
-$ apt-get update
-$ apt-get install -y gcc g++ wget git cmake pkg-config libprotoc-dev protobuf-compiler libprotobuf-dev libssl-dev
-```
-
-To build the software in reporting mode, install these additional dependencies:
-```
-$ apt-get install -y autoconf flex bison
-```
-
-Advanced users can choose to install newer versions of gcc, or the clang compiler.
-
-### Build Boost
-
-Boost 1.70 or later is required. We recommend downloading and compiling boost
-with the following process: After changing to the directory where
-you wish to download and compile boost, run
-```
-$ wget https://boostorg.jfrog.io/artifactory/main/release/1.70.0/source/boost_1_70_0.tar.gz
-$ tar -xzf boost_1_70_0.tar.gz
-$ cd boost_1_70_0
-$ ./bootstrap.sh
-$ ./b2 headers
-$ ./b2 -j $(echo $(nproc)-2 | bc)
-```
-
-### (Optional) Dependencies for Building Source Documentation
-
-Source code documentation is not required for running/debugging rippled. That
-said, the documentation contains some helpful information about specific
-components of the application. For more information on how to install and run
-the necessary components, see [this document](../../docs/README.md)
-
-## Build
-
-### Clone the rippled repository
-
-From a shell:
-
-```
-git clone git@github.com:ripple/rippled.git
-cd rippled
-```
-
-For a stable release, choose the `master` branch or one of the tagged releases
-listed on [GitHub](https://github.com/ripple/rippled/releases).
-
-```
-git checkout master
-```
-
-or to test the latest release candidate, choose the `release` branch.
-
-```
-git checkout release
-```
-
-If you are doing development work and want the latest set of untested
-features, you can consider using the `develop` branch instead.
-
-```
-git checkout develop
-```
-
-### Configure Library Paths
-
-If you didn't persistently set the `BOOST_ROOT` environment variable to the
-directory in which you compiled boost, then you should set it temporarily.
-
-For example, if you built Boost in your home directory `~/boost_1_70_0`, you
-would run the following shell command:
-
-```
-export BOOST_ROOT=~/boost_1_70_0
-```
-
-Alternatively, you can add `DBOOST_ROOT=~/boost_1_70_0` to the command line when
-invoking `cmake`.
-
-### Generate Configuration
-
-All builds should be done in a separate directory from the source tree root
-(a subdirectory is fine). For example, from the root of the ripple source tree:
-
-```
-mkdir build
-cd build
-```
-
-followed by:
-
-```
-cmake -DCMAKE_BUILD_TYPE=Debug ..
-```
-
-If your operating system does not provide static libraries (Arch Linux, and
-Manjaro Linux, for example), you must configure a non-static build by adding
-`-Dstatic=OFF` to the above cmake line.
-
-`CMAKE_BUILD_TYPE` can be changed as desired for `Debug` vs.
-`Release` builds (all four standard cmake build types are supported).
-
-To select a different compiler (most likely gcc will be found by default), pass
-`-DCMAKE_C_COMPILER=` and
-`-DCMAKE_CXX_COMPILER=` when configuring. If you prefer,
-you can instead set `CC` and `CXX` environment variables which cmake will honor.
-
-#### Options During Configuration:
-
-The CMake file defines a number of configure-time options which can be
-examined by running `cmake-gui` or `ccmake` to generated the build. In
-particular, the `unity` option allows you to select between the unity and
-non-unity builds. `unity` builds are faster to compile since they combine
-multiple sources into a single compiliation unit - this is the default if you
-don't specify. `nounity` builds can be helpful for detecting include omissions
-or for finding other build-related issues, but aren't generally needed for
-testing and running.
-
-* `-Dunity=ON` to enable/disable unity builds (defaults to ON)
-* `-Dassert=ON` to enable asserts
-* `-Djemalloc=ON` to enable jemalloc support for heap checking
-* `-Dsan=thread` to enable the thread sanitizer with clang
-* `-Dsan=address` to enable the address sanitizer with clang
-* `-Dstatic=ON` to enable static linking library dependencies
-* `-Dreporting=ON` to build code necessary for reporting mode (defaults to OFF)
-
-Several other infrequently used options are available - run `ccmake` or
-`cmake-gui` for a list of all options.
-
-### Build
-
-Once you have generated the build system, you can run the build via cmake:
-
-```
-cmake --build . -- -j $(echo $(nproc)-2 | bc)
-```
-
-the `-j` parameter in this example tells the build tool to compile several
-files in parallel. This value should be chosen roughly based on the number of
-cores you have available and/or want to use for building.
-
-When the build completes successfully, you will have a `rippled` executable in
-the current directory, which can be used to connect to the network (when
-properly configured) or to run unit tests.
-
-
-#### Optional Installation
-
-The rippled cmake build supports an installation target that will install
-rippled as well as a support library that can be used to sign transactions. In
-order to build and install the files, specify the `install` target when
-building, e.g.:
-
-```
-cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/opt/local ..
-cmake --build . --target install -- -j $(echo $(nproc)-2 | bc)
-```
-
-We recommend specifying `CMAKE_INSTALL_PREFIX` when configuring in order to
-explicitly control the install location for your files. Without this setting,
-cmake will typically install in `/usr/local`. It is also possible to "rehome"
-the installation by specifying the `DESTDIR` env variable during the install phase,
-e.g.:
-
-```
-DESTDIR=~/mylibs cmake --build . --target install -- -j $(echo $(nproc)-2 | bc)
-```
-
-in which case, the files would be installed in the `CMAKE_INSTALL_PREFIX` within
-the specified `DESTDIR` path.
-
-#### Signing Library
-
-If you want to use the signing support library to create an application, there
-are two simple mechanisms with cmake + git that facilitate this.
-
-With either option below, you will have access to a library from the
-rippled project that you can link to in your own project's CMakeLists.txt, e.g.:
-
-```
-target_link_libraries (my-signing-app Ripple::xrpl_core)
-```
-
-##### Option 1: git submodules + add_subdirectory
-
-First, add the rippled repo as a submodule to your project repo:
-
-```
-git submodule add -b master https://github.com/ripple/rippled.git vendor/rippled
-```
-
-change the `vendor/rippled` path as desired for your repo layout. Furthermore,
-change the branch name if you want to track a different rippled branch, such
-as `develop`.
-
-Second, to bring this submodule into your project, just add the rippled subdirectory:
-
-```
-add_subdirectory (vendor/rippled)
-```
-
-##### Option 2: installed rippled + find_package
-
-First, follow the "Optional Installation" instructions above to
-build and install the desired version of rippled.
-
-To make use of the installed files, add the following to your CMakeLists.txt file:
-
-```
-set (CMAKE_MODULE_PATH /opt/local/lib/cmake/ripple ${CMAKE_MODULE_PATH})
-find_package(Ripple REQUIRED)
-```
-
-change the `/opt/local` module path above to match your chosen installation prefix.
-
-## Unit Tests (Recommended)
-
-`rippled` builds a set of unit tests into the server executable. To run these unit
-tests after building, pass the `--unittest` option to the compiled `rippled`
-executable. The executable will exit with summary info after running the unit tests.
-
-## Workaround for a compile error in soci
-
-Compilation errors have been observed with Apple Clang 13.1.6+ and soci v4.x. soci compiles with the `-Werror` flag which causes warnings to be treated as errors. These warnings pertain to style (not correctness). However, they cause the cmake process to fail.
-
-Here's an example of how this looks:
-```
-.../rippled/.nih_c/unix_makefiles/AppleClang_13.1.6.13160021/Debug/src/soci/src/core/session.cpp:450:66: note: in instantiation of function template specialization 'soci::use' requested here
- return prepare << backEnd_->get_column_descriptions_query(), use(table_name, "t");
- ^
-1 error generated.
-```
-
-Please apply the below patch (courtesy of Scott Determan) to remove these errors. `.nih_c/unix_makefiles/AppleClang_13.1.6.13160021/Debug/src/soci/cmake/SociConfig.cmake` file needs to be edited. This file is an example for Mac OS and it might be slightly different for other OS/Architectures.
-
-```
-diff --git a/cmake/SociConfig.cmake b/cmake/SociConfig.cmake
-index 97d907e4..11bcd1f3 100644
---- a/cmake/SociConfig.cmake
-+++ b/cmake/SociConfig.cmake
-@@ -58,8 +58,8 @@ if (MSVC)
-
- else()
-
-- set(SOCI_GCC_CLANG_COMMON_FLAGS
-- "-pedantic -Werror -Wno-error=parentheses -Wall -Wextra -Wpointer-arith -Wcast-align -Wcast-qual -Wfloat-equal -Woverloaded-virtual -Wredundant-decls -Wno-long-long")
-+ set(SOCI_GCC_CLANG_COMMON_FLAGS "")
-+ # "-pedantic -Werror -Wno-error=parentheses -Wall -Wextra -Wpointer-arith -Wcast-align -Wcast-qual -Wfloat-equal -Woverloaded-virtual -Wredundant-decls -Wno-long-long")
-```
+[Build instructions are currently located in `BUILD.md`](../../BUILD.md)
diff --git a/Builds/macos/README.md b/Builds/macos/README.md
index 2a4e28deb68..fce8e824a05 100644
--- a/Builds/macos/README.md
+++ b/Builds/macos/README.md
@@ -1,3 +1 @@
-# macOS Build Instructions
-
-[Build and Run rippled on macOS](https://xrpl.org/build-run-rippled-macos.html)
+[Build instructions are currently located in `BUILD.md`](../../BUILD.md)
diff --git a/README.md b/README.md
index 267ecfb258b..b2d0ff42a3d 100644
--- a/README.md
+++ b/README.md
@@ -10,9 +10,7 @@ The server software that powers the XRP Ledger is called `rippled` and is availa
### Build from Source
-* [Linux](Builds/linux/README.md)
-* [Mac](Builds/macos/README.md) (Not recommended for production)
-* [Windows](Builds/VisualStudio2017/README.md) (Not recommended for production)
+* [Read the build instructions in `BUILD.md`](BUILD.md)
## Key Features of the XRP Ledger
@@ -34,8 +32,12 @@ The server software that powers the XRP Ledger is called `rippled` and is availa
## Source Code
-[![travis-ci.com: Build Status](https://travis-ci.com/ripple/rippled.svg?branch=develop)](https://travis-ci.com/ripple/rippled)
-[![codecov.io: Code Coverage](https://codecov.io/gh/ripple/rippled/branch/develop/graph/badge.svg)](https://codecov.io/gh/ripple/rippled)
+
+Here are some good places to start learning the source code:
+
+- Read the markdown files in the source tree: `src/ripple/**/*.md`.
+- Read [the levelization document](./Builds/levelization) to get an idea of the internal dependency graph.
+- In the big picture, the `main` function constructs an `ApplicationImp` object, which implements the `Application` virtual interface. Almost every component in the application takes an `Application&` parameter in its constructor, typically named `app` and stored as a member variable `app_`. This allows most components to depend on any other component.
### Repository Contents
diff --git a/src/ripple/app/consensus/RCLConsensus.cpp b/src/ripple/app/consensus/RCLConsensus.cpp
index 12a150a4a54..7ba059881c0 100644
--- a/src/ripple/app/consensus/RCLConsensus.cpp
+++ b/src/ripple/app/consensus/RCLConsensus.cpp
@@ -337,7 +337,7 @@ RCLConsensus::Adaptor::onClose(
// pseudo-transactions
auto validations = app_.validators().negativeUNLFilter(
app_.getValidations().getTrustedForLedger(
- prevLedger->info().parentHash));
+ prevLedger->info().parentHash, prevLedger->seq() - 1));
if (validations.size() >= app_.validators().quorum())
{
feeVote_->doVoting(prevLedger, validations, initialSet);
diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp
index ad08b18dd58..7476698ee3a 100644
--- a/src/ripple/app/ledger/impl/LedgerMaster.cpp
+++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp
@@ -341,7 +341,8 @@ LedgerMaster::setValidLedger(std::shared_ptr const& l)
if (!standalone_)
{
auto validations = app_.validators().negativeUNLFilter(
- app_.getValidations().getTrustedForLedger(l->info().hash));
+ app_.getValidations().getTrustedForLedger(
+ l->info().hash, l->info().seq));
times.reserve(validations.size());
for (auto const& val : validations)
times.push_back(val->getSignTime());
@@ -987,7 +988,7 @@ LedgerMaster::checkAccept(uint256 const& hash, std::uint32_t seq)
return;
auto validations = app_.validators().negativeUNLFilter(
- app_.getValidations().getTrustedForLedger(hash));
+ app_.getValidations().getTrustedForLedger(hash, seq));
valCount = validations.size();
if (valCount >= app_.validators().quorum())
{
@@ -1053,7 +1054,8 @@ LedgerMaster::checkAccept(std::shared_ptr const& ledger)
auto const minVal = getNeededValidations();
auto validations = app_.validators().negativeUNLFilter(
- app_.getValidations().getTrustedForLedger(ledger->info().hash));
+ app_.getValidations().getTrustedForLedger(
+ ledger->info().hash, ledger->info().seq));
auto const tvc = validations.size();
if (tvc < minVal) // nothing we can do
{
@@ -1128,7 +1130,7 @@ LedgerMaster::checkAccept(std::shared_ptr const& ledger)
{
// Have not printed the warning before, check if need to print.
auto const vals = app_.getValidations().getTrustedForLedger(
- ledger->info().parentHash);
+ ledger->info().parentHash, ledger->info().seq - 1);
std::size_t higherVersionCount = 0;
std::size_t rippledCount = 0;
for (auto const& v : vals)
diff --git a/src/ripple/app/misc/NegativeUNLVote.cpp b/src/ripple/app/misc/NegativeUNLVote.cpp
index fba02637e51..5c133403b46 100644
--- a/src/ripple/app/misc/NegativeUNLVote.cpp
+++ b/src/ripple/app/misc/NegativeUNLVote.cpp
@@ -198,7 +198,7 @@ NegativeUNLVote::buildScoreTable(
for (int i = 0; i < FLAG_LEDGER_INTERVAL; ++i)
{
for (auto const& v : validations.getTrustedForLedger(
- ledgerAncestors[numAncestors - 1 - i]))
+ ledgerAncestors[numAncestors - 1 - i], seq - 2 - i))
{
if (scoreTable.count(v->getNodeID()))
++scoreTable[v->getNodeID()];
diff --git a/src/ripple/consensus/Validations.h b/src/ripple/consensus/Validations.h
index 46bf4322a5a..a9dbd5585e2 100644
--- a/src/ripple/consensus/Validations.h
+++ b/src/ripple/consensus/Validations.h
@@ -1049,10 +1049,11 @@ class Validations
/** Get trusted full validations for a specific ledger
@param ledgerID The identifier of ledger of interest
+ @param seq The sequence number of ledger of interest
@return Trusted validations associated with ledger
*/
std::vector
- getTrustedForLedger(ID const& ledgerID)
+ getTrustedForLedger(ID const& ledgerID, Seq const& seq)
{
std::vector res;
std::lock_guard lock{mutex_};
@@ -1061,7 +1062,7 @@ class Validations
ledgerID,
[&](std::size_t numValidations) { res.reserve(numValidations); },
[&](NodeID const&, Validation const& v) {
- if (v.trusted() && v.full())
+ if (v.trusted() && v.full() && v.seq() == seq)
res.emplace_back(v.unwrap());
});
diff --git a/src/test/consensus/Validations_test.cpp b/src/test/consensus/Validations_test.cpp
index 79de1fc8063..7dc2086e55c 100644
--- a/src/test/consensus/Validations_test.cpp
+++ b/src/test/consensus/Validations_test.cpp
@@ -613,7 +613,8 @@ class Validations_test : public beast::unit_test::suite
c.setLoadFee(12);
e.setLoadFee(12);
- hash_map> trustedValidations;
+ hash_map, std::vector>
+ trustedValidations;
//----------------------------------------------------------------------
// checkers
@@ -624,14 +625,15 @@ class Validations_test : public beast::unit_test::suite
auto compare = [&]() {
for (auto& it : trustedValidations)
{
- auto const& id = it.first;
+ auto const& id = it.first.first;
+ auto const& seq = it.first.second;
auto const& expectedValidations = it.second;
BEAST_EXPECT(
harness.vals().numTrustedForLedger(id) ==
expectedValidations.size());
BEAST_EXPECT(
- sorted(harness.vals().getTrustedForLedger(id)) ==
+ sorted(harness.vals().getTrustedForLedger(id, seq)) ==
sorted(expectedValidations));
std::uint32_t baseFee = 0;
@@ -653,7 +655,7 @@ class Validations_test : public beast::unit_test::suite
Ledger ledgerAC = h["ac"];
// Add a dummy ID to cover unknown ledger identifiers
- trustedValidations[Ledger::ID{100}] = {};
+ trustedValidations[{Ledger::ID{100}, Ledger::Seq{100}}] = {};
// first round a,b,c agree
for (auto const& node : {a, b, c})
@@ -661,13 +663,14 @@ class Validations_test : public beast::unit_test::suite
auto const val = node.validate(ledgerA);
BEAST_EXPECT(ValStatus::current == harness.add(val));
if (val.trusted())
- trustedValidations[val.ledgerID()].emplace_back(val);
+ trustedValidations[{val.ledgerID(), val.seq()}].emplace_back(
+ val);
}
// d disagrees
{
auto const val = d.validate(ledgerB);
BEAST_EXPECT(ValStatus::current == harness.add(val));
- trustedValidations[val.ledgerID()].emplace_back(val);
+ trustedValidations[{val.ledgerID(), val.seq()}].emplace_back(val);
}
// e only issues partials
{
@@ -681,7 +684,8 @@ class Validations_test : public beast::unit_test::suite
auto const val = node.validate(ledgerAC);
BEAST_EXPECT(ValStatus::current == harness.add(val));
if (val.trusted())
- trustedValidations[val.ledgerID()].emplace_back(val);
+ trustedValidations[{val.ledgerID(), val.seq()}].emplace_back(
+ val);
}
// d now thinks ledger 1, but cannot re-issue a previously used seq
// and attempting it should generate a conflict.
@@ -1035,6 +1039,9 @@ class Validations_test : public beast::unit_test::suite
std::vector const& trustedVals) {
Ledger::ID testID = trustedVals.empty() ? this->genesisLedger.id()
: trustedVals[0].ledgerID();
+ Ledger::Seq testSeq = trustedVals.empty()
+ ? this->genesisLedger.seq()
+ : trustedVals[0].seq();
BEAST_EXPECT(vals.currentTrusted() == trustedVals);
BEAST_EXPECT(vals.getCurrentNodeIDs() == listed);
BEAST_EXPECT(
@@ -1046,7 +1053,8 @@ class Validations_test : public beast::unit_test::suite
else
BEAST_EXPECT(
vals.getPreferred(this->genesisLedger)->second == testID);
- BEAST_EXPECT(vals.getTrustedForLedger(testID) == trustedVals);
+ BEAST_EXPECT(
+ vals.getTrustedForLedger(testID, testSeq) == trustedVals);
BEAST_EXPECT(
vals.numTrustedForLedger(testID) == trustedVals.size());
};