Add dev docs generation to Jenkins:
Fixes: RIPD-1521 Switch to pure doxygen HTML for developer docs. Remove docca/boostbook system. Convert consensus document to markdown. Add existing markdown files to doxygen input set. Fix some image paths and scale images for use with MD links. Rename/cleanup some files for consistency. Add pipeline logic for windows slaves. Add ninja and parallel test run option. Add make doc target build in build-and-test.sh. Cleanup README files. Add nounity windows build. Add link to jenkins summary table. Add rippled_classic build (win). Improve formatting of summary table.
6
.codecov.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
codecov:
|
||||||
|
ci:
|
||||||
|
- ci.ops.ripple.com # add custom jenkins server
|
||||||
|
- !appveyor
|
||||||
|
- !travis
|
||||||
1
.gitignore
vendored
@@ -50,6 +50,7 @@ validators.txt
|
|||||||
|
|
||||||
# Doxygen generated documentation output
|
# Doxygen generated documentation output
|
||||||
HtmlDocumentation
|
HtmlDocumentation
|
||||||
|
docs/html_doc
|
||||||
|
|
||||||
# Xcode user-specific project settings
|
# Xcode user-specific project settings
|
||||||
# Xcode
|
# Xcode
|
||||||
|
|||||||
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
|||||||
[submodule "docs/docca"]
|
|
||||||
path = docs/docca
|
|
||||||
url = https://github.com/vinniefalco/docca.git
|
|
||||||
[submodule "src/nudb/extras/beast"]
|
[submodule "src/nudb/extras/beast"]
|
||||||
path = src/nudb/extras/beast
|
path = src/nudb/extras/beast
|
||||||
url = https://github.com/vinniefalco/Beast.git
|
url = https://github.com/vinniefalco/Beast.git
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ addons:
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# Default BUILD is "scons".
|
|
||||||
|
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
env: GCC_VER=5 BUILD=cmake TARGET=debug
|
env: GCC_VER=5 BUILD=cmake TARGET=debug
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ package() {
|
|||||||
cd "$srcdir/$pkgname"
|
cd "$srcdir/$pkgname"
|
||||||
install -D -m644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
install -D -m644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||||
install -D build/rippled "$pkgdir/usr/bin/rippled"
|
install -D build/rippled "$pkgdir/usr/bin/rippled"
|
||||||
install -D -m644 doc/rippled-example.cfg "$pkgdir/etc/$pkgname/rippled.cfg"
|
install -D -m644 cfg/rippled-example.cfg "$pkgdir/etc/$pkgname/rippled.cfg"
|
||||||
mkdir -p "$pkgdir/var/lib/$pkgname/db"
|
mkdir -p "$pkgdir/var/lib/$pkgname/db"
|
||||||
mkdir -p "$pkgdir/var/log/$pkgname"
|
mkdir -p "$pkgdir/var/log/$pkgname"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ RUN cd src/; scons build/rippled
|
|||||||
RUN cp src/build/rippled rippled; strip rippled
|
RUN cp src/build/rippled rippled; strip rippled
|
||||||
|
|
||||||
# copy default config
|
# copy default config
|
||||||
RUN cp src/doc/rippled-example.cfg rippled.cfg
|
RUN cp src/cfg/rippled-example.cfg rippled.cfg
|
||||||
|
|
||||||
# clean source
|
# clean source
|
||||||
RUN rm -r src
|
RUN rm -r src
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
mkdir -p build/docker/
|
mkdir -p build/docker/
|
||||||
cp doc/rippled-example.cfg build/clang.debug/rippled build/docker/
|
cp cfg/rippled-example.cfg build/clang.debug/rippled build/docker/
|
||||||
cp Builds/Docker/Dockerfile-testnet build/docker/Dockerfile
|
cp Builds/Docker/Dockerfile-testnet build/docker/Dockerfile
|
||||||
mv build/docker/rippled-example.cfg build/docker/rippled.cfg
|
mv build/docker/rippled-example.cfg build/docker/rippled.cfg
|
||||||
strip build/docker/rippled
|
strip build/docker/rippled
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ the rippled server where that file is.
|
|||||||
|
|
||||||
1. Create a directory to hold the configuration file. In this example, the
|
1. Create a directory to hold the configuration file. In this example, the
|
||||||
ripple config directory was created in `C:\Users\joe\ripple\config`.
|
ripple config directory was created in `C:\Users\joe\ripple\config`.
|
||||||
2. Copy the example config file located in `doc\rippled-example.cfg` to the
|
2. Copy the example config file located in `cfg\rippled-example.cfg` to the
|
||||||
new directory and rename it "rippled.cfg".
|
new directory and rename it "rippled.cfg".
|
||||||
3. Read the rippled.cfg file and edit as appropriate.
|
3. Read the rippled.cfg file and edit as appropriate.
|
||||||
|
|
||||||
|
|||||||
@@ -374,15 +374,10 @@ if (WIN32 OR is_xcode)
|
|||||||
# Documentation sources. Only needed for IDEs.
|
# Documentation sources. Only needed for IDEs.
|
||||||
prepend(doc_srcs
|
prepend(doc_srcs
|
||||||
docs/
|
docs/
|
||||||
Jamfile.v2
|
|
||||||
boostbook.dtd
|
|
||||||
consensus.qbk
|
|
||||||
index.xml
|
|
||||||
main.qbk
|
|
||||||
quickref.xml
|
|
||||||
reference.xsl
|
|
||||||
source.dox)
|
source.dox)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE other_docs docs/*.md)
|
||||||
|
list(APPEND doc_srcs "${other_docs}")
|
||||||
set_property(
|
set_property(
|
||||||
SOURCE ${doc_srcs}
|
SOURCE ${doc_srcs}
|
||||||
APPEND
|
APPEND
|
||||||
@@ -484,52 +479,32 @@ list(APPEND targets ${other_target})
|
|||||||
# other_target when the user builds the solution (default when pressing <F7>)
|
# other_target when the user builds the solution (default when pressing <F7>)
|
||||||
set_property(TARGET ${other_target} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD true)
|
set_property(TARGET ${other_target} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD true)
|
||||||
|
|
||||||
find_program(
|
find_package(Doxygen)
|
||||||
B2_EXE
|
if(TARGET Doxygen::doxygen)
|
||||||
NAMES b2
|
if (NOT DEFINED ENV{PLANTUML_JAR})
|
||||||
HINTS ${BOOST_ROOT}
|
message(WARNING
|
||||||
PATHS ${BOOST_ROOT}
|
"PLANTUML_JAR not set - @startuml diagrams will not generate")
|
||||||
DOC "Location of the b2 build executable from Boost")
|
endif()
|
||||||
if(${B2_EXE} STREQUAL "B2_EXE-NOTFOUND")
|
# read the source config and make a modified one
|
||||||
message(WARNING
|
# that points the output files to our build directory
|
||||||
"Boost b2 executable not found. docs target will not be buildable")
|
FILE(READ "${CMAKE_SOURCE_DIR}/docs/source.dox" dox_content)
|
||||||
elseif(NOT BOOST_ROOT)
|
string(REGEX REPLACE "[\t ]*OUTPUT_DIRECTORY[\t ]*=(.*)"
|
||||||
if(Boost_INCLUDE_DIRS)
|
"OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}\n\\1"
|
||||||
set(BOOST_ROOT ${Boost_INCLUDE_DIRS})
|
new_config "${dox_content}")
|
||||||
else()
|
FILE(WRITE "${CMAKE_BINARY_DIR}/source.dox" "${new_config}")
|
||||||
get_filename_component(BOOST_ROOT ${B2_EXE} DIRECTORY)
|
add_custom_target(docs
|
||||||
|
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/source.dox"
|
||||||
|
BYPRODUCTS "${CMAKE_BINARY_DIR}/html_doc/index.html"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/docs"
|
||||||
|
SOURCES "${doc_srcs}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(WARNING
|
||||||
|
"doxygen executable not found. docs target will not be buildable")
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS "3.9.0")
|
||||||
|
message("...consider updating to CMake 3.9.0 or greater for better doxygen support")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
# The value for BOOST_ROOT will be determined based on
|
|
||||||
# 1) The environment BOOST_ROOT
|
|
||||||
# 2) The Boost_INCLUDE_DIRS found by `get_boost`
|
|
||||||
# 3) The folder the `b2` executable is found in.
|
|
||||||
# If those checks don't yield the correct path, BOOST_ROOT
|
|
||||||
# can be defined on the cmake command line:
|
|
||||||
# cmake <path> -DBOOST_ROOT=<boost_path>
|
|
||||||
if(BOOST_ROOT)
|
|
||||||
set(B2_PARAMS "-sBOOST_ROOT=${BOOST_ROOT}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Find bash to help Windows avoid file association problems
|
|
||||||
find_program(
|
|
||||||
BASH_EXE
|
|
||||||
NAMES bash sh
|
|
||||||
DOC "Location of the bash shell executable"
|
|
||||||
)
|
|
||||||
if(${BASH_EXE} STREQUAL "BASH_EXE-NOTFOUND")
|
|
||||||
message(WARNING
|
|
||||||
"Unable to find bash executable. docs target may not be buildable")
|
|
||||||
set(BASH_EXE "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_target(docs
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E env "PATH=$ENV{PATH} " ${BASH_EXE} ./makeqbk.sh
|
|
||||||
COMMAND ${B2_EXE} ${B2_PARAMS}
|
|
||||||
BYPRODUCTS "${CMAKE_SOURCE_DIR}/docs/html/index.html"
|
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/docs"
|
|
||||||
SOURCES "${doc_srcs}"
|
|
||||||
)
|
|
||||||
|
|
||||||
set_startup_project(rippled)
|
set_startup_project(rippled)
|
||||||
|
|
||||||
|
|||||||
11
Jamroot
@@ -1,11 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
#
|
|
||||||
|
|
||||||
import boost ;
|
|
||||||
|
|
||||||
boost.use-project ;
|
|
||||||
|
|
||||||
399
Jenkinsfile
vendored
@@ -74,11 +74,11 @@ try {
|
|||||||
|
|
||||||
if (! collab_found) {
|
if (! collab_found) {
|
||||||
manager.addShortText(
|
manager.addShortText(
|
||||||
"Author of this change is not a collaborator!",
|
'Author of this change is not a collaborator!',
|
||||||
"Crimson",
|
'Crimson',
|
||||||
"white",
|
'white',
|
||||||
"0px",
|
'0px',
|
||||||
"white")
|
'white')
|
||||||
all_status['startup'] =
|
all_status['startup'] =
|
||||||
[false, 'Author Check', "$CHANGE_AUTHOR is not a collaborator!"]
|
[false, 'Author Check', "$CHANGE_AUTHOR is not a collaborator!"]
|
||||||
error "$CHANGE_AUTHOR does not appear to be a collaborator...bailing on this build"
|
error "$CHANGE_AUTHOR does not appear to be a collaborator...bailing on this build"
|
||||||
@@ -88,93 +88,262 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stage ('Parallel Build') {
|
stage ('Parallel Build') {
|
||||||
def variants = [
|
String[][] variants = [
|
||||||
'coverage',
|
['coverage'],
|
||||||
'clang.debug.unity',
|
['docs'],
|
||||||
'clang.debug.nounity',
|
['msvc.debug'],
|
||||||
'gcc.debug.unity',
|
// This one does not currently build (TBD):
|
||||||
'gcc.debug.nounity',
|
//['msvc.debug.nounity'],
|
||||||
'clang.release.unity',
|
['msvc.debug', '', 'PROJECT_NAME=rippled_classic'],
|
||||||
'gcc.release.unity'] as String[]
|
['msvc.release'],
|
||||||
|
['clang.debug.unity'],
|
||||||
|
['clang.debug.unity', '', 'PARALLEL_TESTS=false'],
|
||||||
|
['clang.debug.nounity'],
|
||||||
|
['gcc.debug.unity'],
|
||||||
|
['gcc.debug.nounity'],
|
||||||
|
['clang.release.unity'],
|
||||||
|
['gcc.release.unity'],
|
||||||
|
// add a static build just to make sure it works
|
||||||
|
['gcc.debug.unity', '-Dstatic=true'],
|
||||||
|
// TODO - sanitizer runs currently fail
|
||||||
|
//['gcc.debug.nounity' , '-Dsan=address', 'PARALLEL_TESTS=false'],
|
||||||
|
//['gcc.debug.nounity' , '-Dsan=thread', 'PARALLEL_TESTS=false'],
|
||||||
|
]
|
||||||
|
|
||||||
// create a map of all builds
|
// create a map of all builds
|
||||||
// that we want to run. The map
|
// that we want to run. The map
|
||||||
// is string keys and node{} object values
|
// is string keys and node{} object values
|
||||||
def builds = [:]
|
def builds = [:]
|
||||||
for (int index = 0; index < variants.size(); index++) {
|
for (int index = 0; index < variants.size(); index++) {
|
||||||
def bldtype = variants[index]
|
def bldtype = variants[index][0]
|
||||||
builds[bldtype] = {
|
def cmake_extra = variants[index].size() > 1 ? variants[index][1] : ''
|
||||||
node('rippled-dev') {
|
def bldlabel = bldtype + cmake_extra
|
||||||
|
def extra_env = variants[index].size() > 2 ? variants[index][2..-1] : []
|
||||||
|
for (int j = 0; j < extra_env.size(); j++) {
|
||||||
|
bldlabel += "_" + extra_env[j]
|
||||||
|
}
|
||||||
|
bldlabel = bldlabel.replace('-', '_')
|
||||||
|
bldlabel = bldlabel.replace(' ', '')
|
||||||
|
bldlabel = bldlabel.replace('=', '_')
|
||||||
|
|
||||||
|
def compiler = getFirstPart(bldtype)
|
||||||
|
def target = getSecondPart(bldtype)
|
||||||
|
def config = getFirstPart(target)
|
||||||
|
if (compiler == 'coverage' || compiler == 'docs') {
|
||||||
|
compiler = 'gcc'
|
||||||
|
}
|
||||||
|
def cc =
|
||||||
|
(compiler == 'clang') ? '/opt/llvm-5.0.1/bin/clang' : 'gcc'
|
||||||
|
def cxx =
|
||||||
|
(compiler == 'clang') ? '/opt/llvm-5.0.1/bin/clang++' : 'g++'
|
||||||
|
def ucc = isNoUnity(target) ? 'true' : 'false'
|
||||||
|
def node_type =
|
||||||
|
(compiler == 'msvc') ? 'rippled-win' : 'rippled-dev'
|
||||||
|
// the default disposition for parallel test..disabled
|
||||||
|
// for coverage, enabled otherwise. Can still be overridden
|
||||||
|
// by explicitly setting with extra env settings above.
|
||||||
|
def pt = (compiler == 'coverage') ? 'false' : 'true'
|
||||||
|
|
||||||
|
def env_vars = [
|
||||||
|
"TARGET=${target}",
|
||||||
|
"CONFIG_TYPE=${config}",
|
||||||
|
"COMPILER=${compiler}",
|
||||||
|
"PARALLEL_TESTS=${pt}",
|
||||||
|
'BUILD=cmake',
|
||||||
|
"BUILD_DIR=${bldlabel}",
|
||||||
|
"CMAKE_EXTRA_ARGS=${cmake_extra}",
|
||||||
|
'VERBOSE_BUILD=true']
|
||||||
|
|
||||||
|
builds[bldlabel] = {
|
||||||
|
node(node_type) {
|
||||||
checkout scm
|
checkout scm
|
||||||
dir ('build') {
|
dir ('build') {
|
||||||
deleteDir()
|
deleteDir()
|
||||||
}
|
}
|
||||||
def cdir = upDir(pwd())
|
def cdir = upDir(pwd())
|
||||||
echo "BASEDIR: ${cdir}"
|
echo "BASEDIR: ${cdir}"
|
||||||
def compiler = getCompiler(bldtype)
|
|
||||||
def target = getTarget(bldtype)
|
|
||||||
if (compiler == "coverage") {
|
|
||||||
compiler = 'gcc'
|
|
||||||
}
|
|
||||||
echo "COMPILER: ${compiler}"
|
echo "COMPILER: ${compiler}"
|
||||||
echo "TARGET: ${target}"
|
echo "TARGET: ${target}"
|
||||||
def clang_cc =
|
echo "CONFIG: ${config}"
|
||||||
(compiler == "clang") ? "${LLVM_ROOT}/bin/clang" : ''
|
|
||||||
def clang_cxx =
|
|
||||||
(compiler == "clang") ? "${LLVM_ROOT}/bin/clang++" : ''
|
|
||||||
def ucc = isNoUnity(target) ? 'true' : 'false'
|
|
||||||
echo "USE_CC: ${ucc}"
|
echo "USE_CC: ${ucc}"
|
||||||
withEnv(["CCACHE_BASEDIR=${cdir}",
|
if (compiler == 'msvc') {
|
||||||
"CCACHE_NOHASHDIR=true",
|
env_vars.addAll([
|
||||||
'LCOV_ROOT=""',
|
'BOOST_ROOT=c:\\lib\\boost_1_66',
|
||||||
"TARGET=${target}",
|
'PROJECT_NAME=rippled',
|
||||||
"CC=${compiler}",
|
'MSBUILDDISABLENODEREUSE=1', // this ENV setting is probably redundant since we also pass /nr:false to msbuild
|
||||||
'BUILD=cmake',
|
'OPENSSL_ROOT=c:\\OpenSSL-Win64'])
|
||||||
'VERBOSE_BUILD=true',
|
}
|
||||||
"CLANG_CC=${clang_cc}",
|
else {
|
||||||
"CLANG_CXX=${clang_cxx}",
|
env_vars.addAll([
|
||||||
"USE_CCACHE=${ucc}"])
|
'NINJA_BUILD=false',
|
||||||
{
|
"CCACHE_BASEDIR=${cdir}",
|
||||||
myStage(bldtype)
|
'PLANTUML_JAR=/opt/plantuml/plantuml.jar',
|
||||||
try {
|
'CCACHE_NOHASHDIR=true',
|
||||||
sh "ccache -s > ${bldtype}.txt"
|
"CC=${cc}",
|
||||||
// the devtoolset from SCL gives us a recent gcc. It's
|
"CXX=${cxx}",
|
||||||
// not strictly needed when we are building with clang,
|
'LCOV_ROOT=""',
|
||||||
// but it doesn't seem to interfere either
|
'PATH+CMAKE_BIN=/opt/local/cmake',
|
||||||
sh "source /opt/rh/devtoolset-6/enable && " +
|
'GDB_ROOT=/opt/local/gdb',
|
||||||
"(/usr/bin/time -p ./bin/ci/ubuntu/build-and-test.sh 2>&1) 2>&1 " +
|
'BOOST_ROOT=/opt/local/boost_1_66_0',
|
||||||
">> ${bldtype}.txt"
|
"USE_CCACHE=${ucc}"])
|
||||||
sh "ccache -s >> ${bldtype}.txt"
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
def outstr = readFile("${bldtype}.txt")
|
|
||||||
def st = getResults(outstr)
|
|
||||||
def time = getTime(outstr)
|
|
||||||
def fail_count = getFailures(outstr)
|
|
||||||
outstr = null
|
|
||||||
def txtcolor =
|
|
||||||
fail_count == 0 ? "DarkGreen" : "Crimson"
|
|
||||||
def shortbld = bldtype
|
|
||||||
shortbld = shortbld.replace('debug', 'dbg')
|
|
||||||
shortbld = shortbld.replace('release', 'rel')
|
|
||||||
shortbld = shortbld.replace('unity', 'un')
|
|
||||||
manager.addShortText(
|
|
||||||
"${shortbld}: ${st}, t: ${time}",
|
|
||||||
txtcolor,
|
|
||||||
"white",
|
|
||||||
"0px",
|
|
||||||
"white")
|
|
||||||
archive("${bldtype}.txt")
|
|
||||||
lock('rippled_dev_status') {
|
|
||||||
all_status[bldtype] =
|
|
||||||
[fail_count == 0, bldtype, "${st}, t: ${time}"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (extra_env.size() > 0) {
|
||||||
|
env_vars.addAll(extra_env)
|
||||||
|
}
|
||||||
|
|
||||||
|
withCredentials(
|
||||||
|
[string(
|
||||||
|
credentialsId: 'RIPPLED_CODECOV_TOKEN',
|
||||||
|
variable: 'CODECOV_TOKEN')])
|
||||||
|
{
|
||||||
|
withEnv(env_vars) {
|
||||||
|
myStage(bldlabel)
|
||||||
|
try {
|
||||||
|
if (compiler == 'msvc') {
|
||||||
|
powershell "Remove-Item -Path \"${bldlabel}.txt\" -Force -ErrorAction Ignore"
|
||||||
|
// we capture stdout to variable because I could
|
||||||
|
// not figure out how to make powershell redirect internally
|
||||||
|
output = powershell (
|
||||||
|
returnStdout: true,
|
||||||
|
script: '''
|
||||||
|
# Enable streams 3-6
|
||||||
|
$WarningPreference = 'Continue'
|
||||||
|
$VerbosePreference = 'Continue'
|
||||||
|
$DebugPreference = 'Continue'
|
||||||
|
$InformationPreference = 'Continue'
|
||||||
|
|
||||||
|
Invoke-BatchFile "${env:ProgramFiles(x86)}\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" x86_amd64
|
||||||
|
Get-ChildItem env:* | Sort-Object name
|
||||||
|
cl
|
||||||
|
cmake --version
|
||||||
|
New-Item -ItemType Directory -Force -Path "build/$env:BUILD_DIR" -ErrorAction Stop
|
||||||
|
$sw = [Diagnostics.Stopwatch]::StartNew()
|
||||||
|
try {
|
||||||
|
Push-Location "build/$env:BUILD_DIR"
|
||||||
|
if ($env:NINJA_BUILD -eq "true") {
|
||||||
|
cmake -G"Ninja" -Dtarget="$env:COMPILER.$env:TARGET" -DCMAKE_VERBOSE_MAKEFILE=ON ../..
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cmake -G"Visual Studio 15 2017 Win64" -Dtarget="$env:COMPILER.$env:TARGET" -DCMAKE_VERBOSE_MAKEFILE=ON ../..
|
||||||
|
}
|
||||||
|
if ($LastExitCode -ne 0) { throw "CMake failed" }
|
||||||
|
|
||||||
|
## as of 01/2018, DO NOT USE cmake to run the actual build step. for some
|
||||||
|
## reason, cmake spawning the build under jenkins causes MSBUILD/ninja to
|
||||||
|
## get stuck at the end of the build. Perhaps cmake is spawning
|
||||||
|
## incorrectly or failing to pass certain params
|
||||||
|
|
||||||
|
if ($env:NINJA_BUILD -eq "true") {
|
||||||
|
ninja -j $env:NUMBER_OF_PROCESSORS -v
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msbuild /fl /m /nr:false /p:Configuration="$env:CONFIG_TYPE" /p:Platform=x64 /p:GenerateFullPaths=True /v:normal /nologo /clp:"ShowCommandLine;DisableConsoleColor" "$env:PROJECT_NAME.vcxproj"
|
||||||
|
}
|
||||||
|
if ($LastExitCode -ne 0) { throw "CMake build failed" }
|
||||||
|
|
||||||
|
$exe = "./$env:CONFIG_TYPE/$env:PROJECT_NAME"
|
||||||
|
if ($env:NINJA_BUILD -eq "true") {
|
||||||
|
$exe = "./$env:PROJECT_NAME"
|
||||||
|
}
|
||||||
|
"Exe is at $exe"
|
||||||
|
$params = '--unittest', '--quiet', '--unittest-log'
|
||||||
|
if ($env:PARALLEL_TESTS -eq "true") {
|
||||||
|
$params = $params += "--unittest-jobs=$env:NUMBER_OF_PROCESSORS"
|
||||||
|
}
|
||||||
|
& $exe $params
|
||||||
|
if ($LastExitCode -ne 0) { throw "Unit tests failed" }
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$sw.Stop()
|
||||||
|
$sw.Elapsed
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
''')
|
||||||
|
// if the powershell command fails (has nonzero exit)
|
||||||
|
// then the command above throws, we don't get our output,
|
||||||
|
// and we never create this output file.
|
||||||
|
// SEE https://issues.jenkins-ci.org/browse/JENKINS-44930
|
||||||
|
// Alternatively, figure out how to reliably redirect
|
||||||
|
// all output above to a file (Start/Stop transcript does not work)
|
||||||
|
writeFile(
|
||||||
|
file: "${bldlabel}.txt",
|
||||||
|
text: output)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sh "rm -fv ${bldlabel}.txt"
|
||||||
|
// execute the bld command in a redirecting shell
|
||||||
|
// to capture output
|
||||||
|
sh '''\
|
||||||
|
#!/bin/bash
|
||||||
|
set -ex
|
||||||
|
log_file=''' + "${bldlabel}.txt" + '''
|
||||||
|
exec 3>&1 1>>${log_file} 2>&1
|
||||||
|
ccache -s
|
||||||
|
source /opt/rh/devtoolset-6/enable
|
||||||
|
/usr/bin/time -p ./bin/ci/ubuntu/build-and-test.sh 2>&1
|
||||||
|
ccache -s
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
def outstr = ''
|
||||||
|
def loglink = '[console](' + env.BUILD_URL + '/console)'
|
||||||
|
def logfile = "${bldlabel}.txt"
|
||||||
|
if (fileExists(logfile)) {
|
||||||
|
outstr = readFile(logfile)
|
||||||
|
loglink = "[logfile](" + env.BUILD_URL + "/artifact/${logfile})"
|
||||||
|
}
|
||||||
|
def st = getResults(outstr, bldlabel)
|
||||||
|
def time = getTime(outstr, bldlabel)
|
||||||
|
def fail_count = getFailures(outstr, bldlabel)
|
||||||
|
outstr = null
|
||||||
|
def txtcolor =
|
||||||
|
fail_count == 0 ? 'DarkGreen' : 'Crimson'
|
||||||
|
def shortbld = bldlabel
|
||||||
|
shortbld = shortbld.replace('debug', 'dbg')
|
||||||
|
shortbld = shortbld.replace('release', 'rel')
|
||||||
|
shortbld = shortbld.replace('unity', 'un')
|
||||||
|
manager.addShortText(
|
||||||
|
"${shortbld}: ${st}, t: ${time}",
|
||||||
|
txtcolor,
|
||||||
|
'white',
|
||||||
|
'0px',
|
||||||
|
'white')
|
||||||
|
archive("${bldlabel}.txt")
|
||||||
|
if (bldtype == 'docs') {
|
||||||
|
publishHTML(
|
||||||
|
allowMissing: true,
|
||||||
|
alwaysLinkToLastBuild: false,
|
||||||
|
keepAll: true,
|
||||||
|
reportName: 'Doxygen',
|
||||||
|
reportDir: 'build/docs/html_doc',
|
||||||
|
reportFiles: 'index.html')
|
||||||
|
}
|
||||||
|
def envs = ''
|
||||||
|
for (int j = 0; j < extra_env.size(); j++) {
|
||||||
|
envs += ", <br/>" + extra_env[j]
|
||||||
|
}
|
||||||
|
def cmake_txt = cmake_extra
|
||||||
|
if (cmake_txt != '') {
|
||||||
|
cmake_txt = " <br/>" + cmake_txt
|
||||||
|
}
|
||||||
|
lock('rippled_dev_status') {
|
||||||
|
all_status[bldlabel] =
|
||||||
|
[fail_count == 0, bldtype + cmake_txt + envs, "${st}, t: ${time}", loglink]
|
||||||
|
}
|
||||||
|
} //try-catch-finally
|
||||||
|
} //withEnv
|
||||||
|
} //withCredentials
|
||||||
|
} //node
|
||||||
|
} //builds item
|
||||||
|
} //for variants
|
||||||
|
|
||||||
|
// this actually executes all the builds we just defined
|
||||||
|
// above, in parallel as slaves are available
|
||||||
parallel builds
|
parallel builds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +352,7 @@ finally {
|
|||||||
stage ('Final Status') {
|
stage ('Final Status') {
|
||||||
node {
|
node {
|
||||||
def start_time = new Date()
|
def start_time = new Date()
|
||||||
def sdf = new SimpleDateFormat("yyyyMMdd - HH:mm:ss")
|
def sdf = new SimpleDateFormat('yyyyMMdd - HH:mm:ss')
|
||||||
def datestamp = sdf.format(start_time)
|
def datestamp = sdf.format(start_time)
|
||||||
|
|
||||||
def results = """
|
def results = """
|
||||||
@@ -195,19 +364,19 @@ Built at __${datestamp}__
|
|||||||
|
|
||||||
### Test Results
|
### Test Results
|
||||||
|
|
||||||
Build Type | Result | Status
|
Build Type | Log | Result | Status
|
||||||
---------- | ------ | ------
|
---------- | --- | ------ | ------
|
||||||
"""
|
"""
|
||||||
for ( e in all_status) {
|
for ( e in all_status) {
|
||||||
results += e.value[1] + " | " + e.value[2] + " | " +
|
results += e.value[1] + ' | ' + e.value[3] + ' | ' + e.value[2] + ' | ' +
|
||||||
(e.value[0] ? "PASS :white_check_mark: " : "FAIL :red_circle: ") + "\n"
|
(e.value[0] ? 'PASS :white_check_mark: ' : 'FAIL :red_circle: ') + '\n'
|
||||||
}
|
}
|
||||||
results += "\n"
|
results += '\n'
|
||||||
echo "FINAL BUILD RESULTS"
|
echo 'FINAL BUILD RESULTS'
|
||||||
echo results
|
echo results
|
||||||
|
|
||||||
try {
|
try {
|
||||||
def url_comment = ""
|
def url_comment = ''
|
||||||
if (env.CHANGE_ID && env.CHANGE_ID ==~ /\d+/) {
|
if (env.CHANGE_ID && env.CHANGE_ID ==~ /\d+/) {
|
||||||
//
|
//
|
||||||
// CHANGE_ID indicates we are building a PR
|
// CHANGE_ID indicates we are building a PR
|
||||||
@@ -251,7 +420,7 @@ Build Type | Result | Status
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (comment_id == 0) {
|
if (comment_id == 0) {
|
||||||
echo "no existing status comment found"
|
echo 'no existing status comment found'
|
||||||
}
|
}
|
||||||
|
|
||||||
def body = JsonOutput.toJson([
|
def body = JsonOutput.toJson([
|
||||||
@@ -266,8 +435,8 @@ Build Type | Result | Status
|
|||||||
httpMode: mode,
|
httpMode: mode,
|
||||||
requestBody: body)
|
requestBody: body)
|
||||||
}
|
}
|
||||||
catch (any) {
|
catch (e) {
|
||||||
echo "had a problem interacting with github...status is probably not updated"
|
echo 'had a problem interacting with github...status is probably not updated'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,24 +464,54 @@ ${log}
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonCPS
|
@NonCPS
|
||||||
def getResults(text) {
|
def getResults(text, label) {
|
||||||
// example:
|
// example:
|
||||||
/// 194.5s, 154 suites, 948 cases, 360485 tests total, 0 failures
|
/// 194.5s, 154 suites, 948 cases, 360485 tests total, 0 failures
|
||||||
def matcher = text =~ /(\d+) cases, (\d+) tests total, (\d+) (failure(s?))/
|
// or build log format:
|
||||||
matcher ? matcher[0][1] + " cases, " + matcher[0][3] + " failed" : "no test results"
|
// [msvc.release] 71.3s, 162 suites, 995 cases, 318901 tests total, 1 failure
|
||||||
|
def matcher =
|
||||||
|
text == '' ?
|
||||||
|
manager.getLogMatcher(/\[${label}\].+?(\d+) case[s]?, (\d+) test[s]? total, (\d+) (failure(s?))/) :
|
||||||
|
text =~ /(\d+) case[s]?, (\d+) test[s]? total, (\d+) (failure(s?))/
|
||||||
|
matcher ? matcher[0][1] + ' cases, ' + matcher[0][3] + ' failed' : 'no test results'
|
||||||
}
|
}
|
||||||
|
|
||||||
def getFailures(text) {
|
def getFailures(text, label) {
|
||||||
// example:
|
// [see above for format]
|
||||||
/// 194.5s, 154 suites, 948 cases, 360485 tests total, 0 failures
|
def matcher =
|
||||||
def matcher = text =~ /(\d+) tests total, (\d+) (failure(s?))/
|
text == '' ?
|
||||||
|
manager.getLogMatcher(/\[${label}\].+?(\d+) test[s]? total, (\d+) (failure(s?))/) :
|
||||||
|
text =~ /(\d+) test[s]? total, (\d+) (failure(s?))/
|
||||||
// if we didn't match, then return 1 since something is
|
// if we didn't match, then return 1 since something is
|
||||||
// probably wrong, e.g. maybe the build failed...
|
// probably wrong, e.g. maybe the build failed...
|
||||||
matcher ? matcher[0][2] as Integer : 1i
|
matcher ? matcher[0][2] as Integer : 1i
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonCPS
|
@NonCPS
|
||||||
def getCompiler(bld) {
|
def getTime(text, label) {
|
||||||
|
// look for text following a label 'real' for
|
||||||
|
// wallclock time. Some `time`s report fractional
|
||||||
|
// seconds and we can omit those in what we report
|
||||||
|
def matcher =
|
||||||
|
text == '' ?
|
||||||
|
manager.getLogMatcher(/(?m)^\[${label}\]\s+real\s+(.+)\.(\d+?)[s]?/) :
|
||||||
|
text =~ /(?m)^real\s+(.+)\.(\d+?)[s]?/
|
||||||
|
if (matcher) {
|
||||||
|
return matcher[0][1] + 's'
|
||||||
|
}
|
||||||
|
|
||||||
|
// alternatively, look for powershell elapsed time
|
||||||
|
// format, e.g. :
|
||||||
|
// TotalSeconds : 523.2140529
|
||||||
|
def matcher2 =
|
||||||
|
text == '' ?
|
||||||
|
manager.getLogMatcher(/(?m)^\[${label}\]\s+TotalSeconds\s+:\s+(\d+)\.(\d+?)?/) :
|
||||||
|
text =~ /(?m)^TotalSeconds\s+:\s+(\d+)\.(\d+?)?/
|
||||||
|
matcher2 ? matcher2[0][1] + 's' : 'n/a'
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonCPS
|
||||||
|
def getFirstPart(bld) {
|
||||||
def matcher = bld =~ /^(.+?)\.(.+)$/
|
def matcher = bld =~ /^(.+?)\.(.+)$/
|
||||||
matcher ? matcher[0][1] : bld
|
matcher ? matcher[0][1] : bld
|
||||||
}
|
}
|
||||||
@@ -324,7 +523,7 @@ def isNoUnity(bld) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonCPS
|
@NonCPS
|
||||||
def getTarget(bld) {
|
def getSecondPart(bld) {
|
||||||
def matcher = bld =~ /^(.+?)\.(.+)$/
|
def matcher = bld =~ /^(.+?)\.(.+)$/
|
||||||
matcher ? matcher[0][2] : bld
|
matcher ? matcher[0][2] : bld
|
||||||
}
|
}
|
||||||
@@ -337,12 +536,4 @@ def upDir(path) {
|
|||||||
matcher ? matcher[0][1] : path
|
matcher ? matcher[0][1] : path
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonCPS
|
|
||||||
def getTime(text) {
|
|
||||||
// look for text following a label 'real' for
|
|
||||||
// wallclock time. Some `time`s report fractional
|
|
||||||
// seconds and we can omit those in what we report
|
|
||||||
def matcher = text =~ /(?m)^real\s+(.+)\.(\d+?)[s]?/
|
|
||||||
matcher ? matcher[0][1] + "s" : "n/a"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
20
README.md
@@ -1,10 +1,11 @@
|
|||||||

|
|
||||||
|
|
||||||
**Do you work at a digital asset exchange or wallet provider?**
|
|
||||||
|
|
||||||
Please [contact us](mailto:support@ripple.com). We can help guide your integration.
|
|
||||||
|
|
||||||
# What is Ripple?
|
# What is Ripple?
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> **Do you work at a digital asset exchange or wallet provider?**
|
||||||
|
>
|
||||||
|
> Please [contact us](mailto:support@ripple.com). We can help guide your integration.
|
||||||
|
|
||||||
Ripple is a network of computers which use the [Ripple consensus algorithm](https://www.youtube.com/watch?v=pj1QVb1vlC0) to atomically settle and record
|
Ripple is a network of computers which use the [Ripple consensus algorithm](https://www.youtube.com/watch?v=pj1QVb1vlC0) to atomically settle and record
|
||||||
transactions on a secure distributed database, the Ripple Consensus Ledger
|
transactions on a secure distributed database, the Ripple Consensus Ledger
|
||||||
(RCL). Because of its distributed nature, the RCL offers transaction immutability
|
(RCL). Because of its distributed nature, the RCL offers transaction immutability
|
||||||
@@ -36,7 +37,7 @@ multiple trading parties, who each layer costs to the transaction. Thin
|
|||||||
liquidity and many intermediary trading parties make competitive pricing
|
liquidity and many intermediary trading parties make competitive pricing
|
||||||
challenging.
|
challenging.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### XRP as a Bridge Currency
|
### XRP as a Bridge Currency
|
||||||
Ripple can bridge even exotic currency pairs directly through XRP. Similar to
|
Ripple can bridge even exotic currency pairs directly through XRP. Similar to
|
||||||
@@ -47,7 +48,7 @@ counterparty risk, or additional operational costs. By using XRP, liquidity
|
|||||||
providers can specialize in certain currency corridors, reduce operational
|
providers can specialize in certain currency corridors, reduce operational
|
||||||
costs, and ultimately, offer more competitive FX pricing.
|
costs, and ultimately, offer more competitive FX pricing.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# rippled - Ripple server
|
# rippled - Ripple server
|
||||||
`rippled` is the reference server implementation of the Ripple
|
`rippled` is the reference server implementation of the Ripple
|
||||||
@@ -68,7 +69,8 @@ ISC license. See the LICENSE file for more details.
|
|||||||
| ./bin | Scripts and data files for Ripple integrators. |
|
| ./bin | Scripts and data files for Ripple integrators. |
|
||||||
| ./build | Intermediate and final build outputs. |
|
| ./build | Intermediate and final build outputs. |
|
||||||
| ./Builds| Platform or IDE-specific project files. |
|
| ./Builds| Platform or IDE-specific project files. |
|
||||||
| ./doc | Documentation and example configuration files. |
|
| ./docs | Source documentation files and doxygen config. |
|
||||||
|
| ./cfg | Example configuration files. |
|
||||||
| ./src | Source code. |
|
| ./src | Source code. |
|
||||||
|
|
||||||
Some of the directories under `src` are external repositories inlined via
|
Some of the directories under `src` are external repositories inlined via
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||

|
# Release Notes
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
This document contains the release notes for `rippled`, the reference server implementation of the Ripple protocol. To learn more about how to build and run a `rippled` server, visit https://ripple.com/build/rippled-setup/
|
This document contains the release notes for `rippled`, the reference server implementation of the Ripple protocol. To learn more about how to build and run a `rippled` server, visit https://ripple.com/build/rippled-setup/
|
||||||
|
|
||||||
**Do you work at a digital asset exchange or wallet provider?**
|
> **Do you work at a digital asset exchange or wallet provider?**
|
||||||
|
>
|
||||||
Please [contact us](mailto:support@ripple.com). We can help guide your integration.
|
> Please [contact us](mailto:support@ripple.com). We can help guide your integration.
|
||||||
|
|
||||||
## Updating `rippled`
|
## Updating `rippled`
|
||||||
|
|
||||||
If you are using Red Hat Enterprise Linux 7 or CentOS 7, you can [update using `yum`](https://ripple.com/build/rippled-setup/#updating-rippled). For other platforms, please [compile from source](https://wiki.ripple.com/Rippled_build_instructions).
|
If you are using Red Hat Enterprise Linux 7 or CentOS 7, you can [update using `yum`](https://ripple.com/build/rippled-setup/#updating-rippled). For other platforms, please [compile from source](https://wiki.ripple.com/Rippled_build_instructions).
|
||||||
|
|
||||||
# Releases
|
# Releases
|
||||||
|
|||||||
@@ -6,6 +6,12 @@
|
|||||||
set -ex
|
set -ex
|
||||||
__dirname=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
__dirname=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||||
echo "using CC: $CC"
|
echo "using CC: $CC"
|
||||||
|
"${CC}" --version
|
||||||
|
COMPNAME=$(basename $CC)
|
||||||
|
echo "using CXX: ${CXX:-notset}"
|
||||||
|
if [[ $CXX ]]; then
|
||||||
|
"${CXX}" --version
|
||||||
|
fi
|
||||||
echo "using TARGET: $TARGET"
|
echo "using TARGET: $TARGET"
|
||||||
|
|
||||||
# Ensure APP defaults to rippled if it's not set.
|
# Ensure APP defaults to rippled if it's not set.
|
||||||
@@ -25,42 +31,69 @@ else
|
|||||||
time=
|
time=
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${BUILD:-scons} == "cmake" ]]; then
|
if [[ ${BUILD:-cmake} == "cmake" ]]; then
|
||||||
echo "cmake building ${APP}"
|
echo "cmake building ${APP}"
|
||||||
CMAKE_EXTRA_ARGS=" -DCMAKE_VERBOSE_MAKEFILE=ON"
|
: ${CMAKE_EXTRA_ARGS:=""}
|
||||||
CMAKE_TARGET=$CC.$TARGET
|
if [[ ${NINJA_BUILD:-} == true ]]; then
|
||||||
BUILDARGS=" -j${JOBS}"
|
CMAKE_EXTRA_ARGS+=" -G Ninja"
|
||||||
if [[ ${VERBOSE_BUILD:-} == true ]]; then
|
|
||||||
# TODO: if we use a different generator, this
|
|
||||||
# option to build verbose would need to change:
|
|
||||||
BUILDARGS+=" verbose=1"
|
|
||||||
fi
|
fi
|
||||||
|
CMAKE_TARGET=${COMPNAME}.${TARGET}
|
||||||
if [[ ${CI:-} == true ]]; then
|
if [[ ${CI:-} == true ]]; then
|
||||||
CMAKE_TARGET=$CMAKE_TARGET.ci
|
CMAKE_TARGET=$CMAKE_TARGET.ci
|
||||||
fi
|
fi
|
||||||
|
#
|
||||||
|
# allow explicit setting of the name of the build
|
||||||
|
# dir, otherwise default to the CMAKE_TARGET value
|
||||||
|
#
|
||||||
|
: "${BUILD_DIR:=$CMAKE_TARGET}"
|
||||||
|
BUILDARGS=" -j${JOBS}"
|
||||||
|
if [[ ${VERBOSE_BUILD:-} == true ]]; then
|
||||||
|
CMAKE_EXTRA_ARGS+=" -DCMAKE_VERBOSE_MAKEFILE=ON"
|
||||||
|
|
||||||
|
# TODO: if we use a different generator, this
|
||||||
|
# option to build verbose would need to change:
|
||||||
|
if [[ ${NINJA_BUILD:-} == true ]]; then
|
||||||
|
BUILDARGS+=" -v"
|
||||||
|
else
|
||||||
|
BUILDARGS+=" verbose=1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if [[ ${USE_CCACHE:-} == true ]]; then
|
if [[ ${USE_CCACHE:-} == true ]]; then
|
||||||
echo "using ccache with basedir [${CCACHE_BASEDIR:-}]"
|
echo "using ccache with basedir [${CCACHE_BASEDIR:-}]"
|
||||||
CMAKE_EXTRA_ARGS+=" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
|
CMAKE_EXTRA_ARGS+=" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
|
||||||
fi
|
fi
|
||||||
if [ -d "build/${CMAKE_TARGET}" ]; then
|
if [ -d "build/${BUILD_DIR}" ]; then
|
||||||
rm -rf "build/${CMAKE_TARGET}"
|
rm -rf "build/${BUILD_DIR}"
|
||||||
fi
|
fi
|
||||||
mkdir -p "build/${CMAKE_TARGET}"
|
|
||||||
pushd "build/${CMAKE_TARGET}"
|
mkdir -p "build/${BUILD_DIR}"
|
||||||
|
pushd "build/${BUILD_DIR}"
|
||||||
$time cmake ../.. -Dtarget=$CMAKE_TARGET ${CMAKE_EXTRA_ARGS}
|
$time cmake ../.. -Dtarget=$CMAKE_TARGET ${CMAKE_EXTRA_ARGS}
|
||||||
$time cmake --build . -- $BUILDARGS
|
if [[ ${TARGET} == "docs" ]]; then
|
||||||
if [[ ${BUILD_BOTH:-} == true ]]; then
|
$time cmake --build . --target docs -- $BUILDARGS
|
||||||
if [[ ${TARGET} == *.unity ]]; then
|
## mimic the standard test output for docs build
|
||||||
$time cmake --build . --target rippled_classic -- $BUILDARGS
|
## to make controlling processes like jenkins happy
|
||||||
|
if [ -f html_doc/index.html ]; then
|
||||||
|
echo "1 case, 1 test total, 0 failures"
|
||||||
else
|
else
|
||||||
$time cmake --build . --target rippled_unity -- $BUILDARGS
|
echo "1 case, 1 test total, 1 failures"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
$time cmake --build . -- $BUILDARGS
|
||||||
|
if [[ ${BUILD_BOTH:-} == true ]]; then
|
||||||
|
if [[ ${TARGET} == *.unity ]]; then
|
||||||
|
cmake --build . --target rippled_classic -- $BUILDARGS
|
||||||
|
else
|
||||||
|
cmake --build . --target rippled_unity -- $BUILDARGS
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
export APP_PATH="$PWD/build/${CMAKE_TARGET}/${APP}"
|
export APP_PATH="$PWD/build/${BUILD_DIR}/${APP}"
|
||||||
echo "using APP_PATH: $APP_PATH"
|
echo "using APP_PATH: $APP_PATH"
|
||||||
else
|
else
|
||||||
export APP_PATH="$PWD/build/$CC.$TARGET/${APP}"
|
export APP_PATH="$PWD/build/${COMPNAME}.${TARGET}/${APP}"
|
||||||
echo "using APP_PATH: $APP_PATH"
|
echo "using APP_PATH: $APP_PATH"
|
||||||
# Make sure vcxproj is up to date
|
# Make sure vcxproj is up to date
|
||||||
$time scons vcxproj
|
$time scons vcxproj
|
||||||
@@ -68,21 +101,21 @@ else
|
|||||||
# $CC will be either `clang` or `gcc`
|
# $CC will be either `clang` or `gcc`
|
||||||
# http://docs.travis-ci.com/user/migrating-from-legacy/?utm_source=legacy-notice&utm_medium=banner&utm_campaign=legacy-upgrade
|
# http://docs.travis-ci.com/user/migrating-from-legacy/?utm_source=legacy-notice&utm_medium=banner&utm_campaign=legacy-upgrade
|
||||||
# indicates that 2 cores are available to containers.
|
# indicates that 2 cores are available to containers.
|
||||||
$time scons -j${JOBS} $CC.$TARGET
|
$time scons -j${JOBS} ${COMPNAME}.$TARGET
|
||||||
fi
|
fi
|
||||||
# We can be sure we're using the build/$CC.$TARGET variant
|
|
||||||
# (-f so never err)
|
|
||||||
rm -f build/${APP}
|
|
||||||
|
|
||||||
# See what we've actually built
|
# See what we've actually built
|
||||||
ldd $APP_PATH
|
ldd $APP_PATH
|
||||||
|
|
||||||
if [[ ${APP} == "rippled" ]]; then
|
if [[ ${APP} == "rippled" ]]; then
|
||||||
export APP_ARGS+=" --unittest --quiet --unittest-log"
|
APP_ARGS+="--unittest --quiet --unittest-log"
|
||||||
# Only report on src/ripple files
|
# Only report on src/ripple files
|
||||||
export LCOV_FILES="*/src/ripple/*"
|
export LCOV_FILES="*/src/ripple/*"
|
||||||
# Nothing to explicitly exclude
|
# Nothing to explicitly exclude
|
||||||
export LCOV_EXCLUDE_FILES="LCOV_NO_EXCLUDE"
|
export LCOV_EXCLUDE_FILES="LCOV_NO_EXCLUDE"
|
||||||
|
if [[ $TARGET != "coverage" && ${PARALLEL_TESTS:-} == true ]]; then
|
||||||
|
APP_ARGS+=" --unittest-jobs ${JOBS}"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
: ${APP_ARGS:=}
|
: ${APP_ARGS:=}
|
||||||
: ${LCOV_FILES:="*/src/*"}
|
: ${LCOV_FILES:="*/src/*"}
|
||||||
@@ -106,6 +139,7 @@ if [[ $TARGET == debug* && -v GDB_ROOT && -x $GDB_ROOT/bin/gdb ]]; then
|
|||||||
$GDB_ROOT/bin/gdb -v
|
$GDB_ROOT/bin/gdb -v
|
||||||
# Execute unit tests under gdb, printing a call stack
|
# Execute unit tests under gdb, printing a call stack
|
||||||
# if we get a crash.
|
# if we get a crash.
|
||||||
|
export APP_ARGS
|
||||||
$GDB_ROOT/bin/gdb -return-child-result -quiet -batch \
|
$GDB_ROOT/bin/gdb -return-child-result -quiet -batch \
|
||||||
-ex "set env MALLOC_CHECK_=3" \
|
-ex "set env MALLOC_CHECK_=3" \
|
||||||
-ex "set print thread-events off" \
|
-ex "set print thread-events off" \
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
A list of rippled version numbers, and the Github pull requests they contain.
|
|
||||||
|
|
||||||
0.28.0-b12: Includes pulls 836, 887, 902, 903 and 904.
|
|
||||||
0.28.0-b13: Includes pulls 906, 912, 913, 914 and 915.
|
|
||||||
0.28.0-b14: Includes pulls 907, 910, 922 and 923.
|
|
||||||
0.28.0-b15: Includes pulls 832, 870, 879, 883, 911, 916, 919, 920, 924, 925 and 928. FAILED pulls 909 and 926.
|
|
||||||
0.28.0-b16: Includes pulls 909, 926, 929, 931, 932, 935 and 934.
|
|
||||||
0.28.0-b17: Includes pulls 927, 939, 940, 943, 944, 945 and 949.
|
|
||||||
0.28.0-b18: Includes pulls 930, 946, 947, 948, 951, 952, 953, 954, 955, 956, 959, 960 and 962.
|
|
||||||
0.29.0-b19: Includes pulls 967, 969 and 971.
|
|
||||||
0.29.0-b20: Includes pulls 935, 942, 957, 958, 963, 964, 965, 966, 968, 972, 973, 974 and 975.
|
|
||||||
0.29.0-b21: Includes pulls 970 and 976.
|
|
||||||
0.28.1-b4: Includes pulls 968, 998, 1005, 1008, 1010, 1011 and 1012.
|
|
||||||
0.28.1-b6: Includes pulls 983, 984, 1013, 1023 and 1024.
|
|
||||||
0.28.1-b8: Includes pulls 988, 1009, 1014, 1019, 1029, 1031, 1033, 1034 and 1035.
|
|
||||||
0.28.1-b9: Includes pulls 1026, 1030, 1036, 1037, 1038, 1040, and 1041.
|
|
||||||
0.28.1-rc2: Includes pulls 1044
|
|
||||||
0.28.1-rc3: Includes pulls 1052 and 1055.
|
|
||||||
0.28.1: Includes pulls 1056, 1059 and 1062, 1063.
|
|
||||||
0.28.2-b1: Includes pulls 866, 1045, 1046, 1047, 1050, 1051, 1057
|
|
||||||
0.28.2-b2: Includes pulls 1058, 1061, 1064 and 1065
|
|
||||||
0.28.2-b3: Includes pulls 1066, 1067, 1068
|
|
||||||
0.28.2-b4: Includes pulls 1060, 1069, 1071, 1072, 1075 and 1076.
|
|
||||||
0.28.2-b5: Includes pulls 1073, 1074, 1081, 1083, 1084, 1087, 1089, 1090, 1091
|
|
||||||
0.28.2-b6: Includes pulls 1085, 1093, 1094, 1096, 1101, 1102, 1105
|
|
||||||
0.28.2-b7: Includes pulls 1077, 1080, 1086, 1095, 1098, 1106 and 1112.
|
|
||||||
0.28.2-b8: Includes pulls 1078, 1100, 1108, 1114, 1118, 1119 and 1121.
|
|
||||||
0.28.2-b9: Includes pulls 1053, 1109, 1111, 1117, 1122 and 1123.
|
|
||||||
0.29.1-b11: Includes pulls 1279, 1271, 1289, 1291, 1290, 1267, 1294, 1276, 1231, and 1286.
|
|
||||||
2304
doc/Doxyfile
@@ -1,126 +0,0 @@
|
|||||||
#
|
|
||||||
# Sample ripple.txt
|
|
||||||
#
|
|
||||||
# More information: https://ripple.com/wiki/Ripple.txt
|
|
||||||
#
|
|
||||||
# Publishing this file allows a site to declare in a trustworthy manor ripple
|
|
||||||
# associated information.
|
|
||||||
#
|
|
||||||
# This file is stored on the web server for a domain. This file is searched
|
|
||||||
# for in the following order:
|
|
||||||
# - https://ripple.DOMAIN/ripple.txt
|
|
||||||
# - https://www.DOMAIN/ripple.txt
|
|
||||||
# - https://DOMAIN/ripple.txt
|
|
||||||
#
|
|
||||||
# The server MUST set the following HTTP header when serving this file:
|
|
||||||
# Access-Control-Allow-Origin: *
|
|
||||||
#
|
|
||||||
# This file is UTF-8 with Dos, UNIX, or Mac style end of lines.
|
|
||||||
# Blank lines and lines beginning with '#' are ignored.
|
|
||||||
# Undefined sections are reserved.
|
|
||||||
# No escapes are currently defined.
|
|
||||||
#
|
|
||||||
# IMPORTANT: Please remove these comments before publishing this file. Doing so
|
|
||||||
# makes the file much more readable to humans trying to find info on your site.
|
|
||||||
#
|
|
||||||
# [expires]
|
|
||||||
# Number of days after which this file should be considered expire. Clients
|
|
||||||
# are expected to check this file when they have cause to believe it has
|
|
||||||
# changed or expired. For example, if a client discovers an account declares
|
|
||||||
# that it is associated with the domain, it should check to see if this file
|
|
||||||
# has been updated. If an expiration date is not declared, the default
|
|
||||||
# expiration for this file is 30 days.
|
|
||||||
#
|
|
||||||
# Example: 30
|
|
||||||
#
|
|
||||||
# [accounts]
|
|
||||||
# Only valid in "ripple.txt". A list of accounts that are declared to be
|
|
||||||
# controlled by this domain. A client wishing to indicate that an account is
|
|
||||||
# verified as belonging to a domain will be show the account with a green
|
|
||||||
# background. A client can verify that an account belongs to a domain by
|
|
||||||
# checking if the account's root entry mentions the domain containing this
|
|
||||||
# file and this file found at the domain mentions the account in this
|
|
||||||
# section.
|
|
||||||
#
|
|
||||||
# Example: rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
|
|
||||||
#
|
|
||||||
# [hotwallets]
|
|
||||||
# Only valid in "ripple.txt". A list of accounts that are declared to be
|
|
||||||
# controlled by this domain and used as hotwallets.
|
|
||||||
#
|
|
||||||
# Example: rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
|
|
||||||
#
|
|
||||||
# [validation_public_key]:
|
|
||||||
# Only valid in "ripple.txt". A validation public key that is declared
|
|
||||||
# to be used by this domain for validating ledgers and that it is the
|
|
||||||
# authorized signature for the domain. This does not imply that a node
|
|
||||||
# serving the Ripple protocol is avilable at the web host providing the
|
|
||||||
# file.
|
|
||||||
#
|
|
||||||
# Example: n9MZTnHe5D5Q2cgE8oV2usFwRqhUvEA8MwP5Mu1XVD6TxmssPRev
|
|
||||||
#
|
|
||||||
# [domain]:
|
|
||||||
# Mandatory in "ripple.txt".
|
|
||||||
# Only valid in "ripple.txt".
|
|
||||||
# Must match location of file.
|
|
||||||
#
|
|
||||||
# Example: google.com
|
|
||||||
#
|
|
||||||
# [ips]:
|
|
||||||
# Only valid in "rippled.cfg", "ripple.txt", and the referered [ips_url].
|
|
||||||
# List of ips where the Newcoin protocol is avialable.
|
|
||||||
# One ipv4 or ipv6 address per line.
|
|
||||||
# A port may optionally be specified after adding a space to the address.
|
|
||||||
# By convention, if known, IPs are listed in from most to least trusted.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# 192.168.0.1
|
|
||||||
# 192.168.0.1 3939
|
|
||||||
# 2001:0db8:0100:f101:0210:a4ff:fee3:9566
|
|
||||||
#
|
|
||||||
# [validators]:
|
|
||||||
# Only valid in "rippled.cfg", "ripple.txt", and the referered [validators_url].
|
|
||||||
# List of Ripple validators this node recommends.
|
|
||||||
#
|
|
||||||
# For domains, rippled will probe for https web servers at the specied
|
|
||||||
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
|
|
||||||
#
|
|
||||||
# These are encoded 257-bit secp256k1 public keys.
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# redstem.com
|
|
||||||
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
|
|
||||||
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
|
|
||||||
#
|
|
||||||
# [ips_url]:
|
|
||||||
# Only valid in "ripple.txt".
|
|
||||||
# https URL to a similarily formatted file containing [ips].
|
|
||||||
#
|
|
||||||
# Example: https://google.com/ripple_ips.txt
|
|
||||||
#
|
|
||||||
# [validators_url]:
|
|
||||||
# Only valid in "ripple.txt".
|
|
||||||
# https URL to a similarily formatted file containing [validators].
|
|
||||||
#
|
|
||||||
# Example: https://google.com/ripple_validators.txt
|
|
||||||
#
|
|
||||||
# [currencies]:
|
|
||||||
# This section allows a site to declare currencies it currently issues.
|
|
||||||
#
|
|
||||||
# Examples: (multiple allowed one per line)
|
|
||||||
# USD
|
|
||||||
# BTC
|
|
||||||
# LTC
|
|
||||||
#
|
|
||||||
|
|
||||||
[validation_public_key]
|
|
||||||
n9MZTnHe5D5Q2cgE8oV2usFwRqhUvEA8MwP5Mu1XVD6TxmssPRev
|
|
||||||
|
|
||||||
[domain]
|
|
||||||
loss
|
|
||||||
|
|
||||||
[ips]
|
|
||||||
192.168.0.5
|
|
||||||
|
|
||||||
[validators]
|
|
||||||
redstem.com
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
# Form
|
# Code Style Cheat Sheet
|
||||||
|
|
||||||
|
## Form
|
||||||
|
|
||||||
- One class per header file.
|
- One class per header file.
|
||||||
- Place each data member on its own line.
|
- Place each data member on its own line.
|
||||||
@@ -11,7 +13,7 @@
|
|||||||
- Order class declarations as types, public, protected, private, then data.
|
- Order class declarations as types, public, protected, private, then data.
|
||||||
- Prefer 'private' over 'protected'
|
- Prefer 'private' over 'protected'
|
||||||
|
|
||||||
# Function
|
## Function
|
||||||
|
|
||||||
- Minimize external dependencies
|
- Minimize external dependencies
|
||||||
* Pass options in the ctor instead of using theConfig
|
* Pass options in the ctor instead of using theConfig
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Coding Standards
|
# Coding Standards
|
||||||
|
|
||||||
Coding standards used here gradually evolve and propagate through
|
Coding standards used here gradually evolve and propagate through
|
||||||
@@ -1,22 +1,31 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
RUN apt-get update
|
RUN apt -y update
|
||||||
RUN apt-get -y install build-essential g++ git libbz2-dev wget python-dev
|
RUN apt -y upgrade
|
||||||
|
RUN apt -y install build-essential g++ git libbz2-dev wget python-dev
|
||||||
|
RUN apt -y install cmake flex bison graphviz graphviz-dev libicu-dev
|
||||||
|
RUN apt -y install jarwrapper java-common
|
||||||
|
|
||||||
# Install Boost
|
RUN cd /tmp
|
||||||
ENV BOOST_SHA 440a59f8bc4023dbe6285c9998b0f7fa288468b889746b1ef00e8b36c559dce1
|
ENV CM_INSTALLER=cmake-3.10.0-rc3-Linux-x86_64.sh
|
||||||
RUN wget https://sourceforge.net/projects/boost/files/boost/1.62.0/boost_1_62_0.tar.gz
|
ENV CM_VER_DIR=/opt/local/cmake-3.10.0
|
||||||
RUN echo "$BOOST_SHA boost_1_62_0.tar.gz" | sha256sum -c
|
RUN cd /tmp && wget https://cmake.org/files/v3.10/$CM_INSTALLER && chmod a+x $CM_INSTALLER
|
||||||
RUN tar xzf boost_1_62_0.tar.gz
|
RUN mkdir -p $CM_VER_DIR
|
||||||
RUN cd boost_1_62_0 && ./bootstrap.sh --prefix=/usr/local
|
RUN ln -s $CM_VER_DIR /opt/local/cmake
|
||||||
RUN cd boost_1_62_0 && ./b2 install
|
RUN /tmp/$CM_INSTALLER --prefix=$CM_VER_DIR --exclude-subdir
|
||||||
ENV BOOST_ROOT=/boost_1_62_0
|
RUN rm -f /tmp/$CM_INSTALLER
|
||||||
|
|
||||||
# Install dependencies
|
RUN cd /tmp && wget https://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.14.src.tar.gz
|
||||||
RUN apt-get -y install doxygen
|
RUN cd /tmp && tar xvf doxygen-1.8.14.src.tar.gz
|
||||||
RUN apt-get -y install xsltproc
|
RUN mkdir -p /tmp/doxygen-1.8.14/build
|
||||||
|
RUN cd /tmp/doxygen-1.8.14/build && /opt/local/cmake/bin/cmake -G "Unix Makefiles" ..
|
||||||
|
RUN cd /tmp/doxygen-1.8.14/build && make -j2
|
||||||
|
RUN cd /tmp/doxygen-1.8.14/build && make install
|
||||||
|
RUN rm -f /tmp/doxygen-1.8.14.src.tar.gz
|
||||||
|
RUN rm -rf /tmp/doxygen-1.8.14
|
||||||
|
|
||||||
CMD cd /opt/rippled/docs && \
|
RUN mkdir -p /opt/plantuml
|
||||||
chmod +x makeqbk.sh && \
|
RUN wget -O /opt/plantuml/plantuml.jar http://sourceforge.net/projects/plantuml/files/plantuml.jar/download
|
||||||
./makeqbk.sh && \
|
ENV PLANTUML_JAR=/opt/plantuml/plantuml.jar
|
||||||
$BOOST_ROOT/b2
|
|
||||||
|
CMD cd /opt/rippled/docs && doxygen source.dox
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
#
|
|
||||||
|
|
||||||
import os ;
|
|
||||||
|
|
||||||
local broot = [ os.environ BOOST_ROOT ] ;
|
|
||||||
|
|
||||||
project rippled/doc ;
|
|
||||||
|
|
||||||
using boostbook ;
|
|
||||||
using quickbook ;
|
|
||||||
using doxygen ;
|
|
||||||
|
|
||||||
path-constant out : . ;
|
|
||||||
|
|
||||||
install stylesheets
|
|
||||||
:
|
|
||||||
$(broot)/doc/src/boostbook.css
|
|
||||||
:
|
|
||||||
<location>$(out)/html
|
|
||||||
;
|
|
||||||
|
|
||||||
explicit stylesheets ;
|
|
||||||
|
|
||||||
install images
|
|
||||||
:
|
|
||||||
[ glob $(broot)/doc/src/images/*.png ]
|
|
||||||
:
|
|
||||||
<location>$(out)/html/images
|
|
||||||
;
|
|
||||||
|
|
||||||
explicit images ;
|
|
||||||
|
|
||||||
install callouts
|
|
||||||
:
|
|
||||||
[ glob $(broot)/doc/src/images/callouts/*.png ]
|
|
||||||
:
|
|
||||||
<location>$(out)/html/images/callouts
|
|
||||||
;
|
|
||||||
|
|
||||||
explicit callout ;
|
|
||||||
|
|
||||||
install consensus_images
|
|
||||||
:
|
|
||||||
[ glob images/consensus/*.png ]
|
|
||||||
:
|
|
||||||
<location>$(out)/html/images/consensus
|
|
||||||
;
|
|
||||||
|
|
||||||
explicit consensus_images ;
|
|
||||||
|
|
||||||
xml doc
|
|
||||||
:
|
|
||||||
main.qbk
|
|
||||||
:
|
|
||||||
<location>temp
|
|
||||||
<include>$(broot)/tools/boostbook/dtd
|
|
||||||
;
|
|
||||||
|
|
||||||
boostbook boostdoc
|
|
||||||
:
|
|
||||||
doc
|
|
||||||
:
|
|
||||||
<xsl:param>chapter.autolabel=0
|
|
||||||
<xsl:param>boost.root=$(broot)
|
|
||||||
<xsl:param>chunk.first.sections=1 # Chunk the first top-level section?
|
|
||||||
<xsl:param>chunk.section.depth=8 # Depth to which sections should be chunked
|
|
||||||
<xsl:param>generate.section.toc.level=2 # Control depth of TOC generation in sections
|
|
||||||
<xsl:param>toc.max.depth=2 # How many levels should be created for each TOC?
|
|
||||||
<xsl:param>toc.section.depth=2 # How deep should recursive sections appear in the TOC?
|
|
||||||
<xsl:param>generate.toc="chapter toc section toc"
|
|
||||||
:
|
|
||||||
<location>temp
|
|
||||||
<dependency>stylesheets
|
|
||||||
<dependency>images
|
|
||||||
<dependency>consensus_images
|
|
||||||
;
|
|
||||||
@@ -13,21 +13,6 @@ relative to the `docs/` directory.
|
|||||||
Install these dependencies:
|
Install these dependencies:
|
||||||
|
|
||||||
1. Install [Doxygen](http://www.stack.nl/~dimitri/doxygen/download.html)
|
1. Install [Doxygen](http://www.stack.nl/~dimitri/doxygen/download.html)
|
||||||
2. Download the following zip files from [xsltproc](https://www.zlatkovic.com/pub/libxml/)
|
|
||||||
(Alternate download: ftp://ftp.zlatkovic.com/libxml/),
|
|
||||||
and extract the `bin\` folder contents into any folder in your path.
|
|
||||||
* iconv
|
|
||||||
* libxml2
|
|
||||||
* libxslt
|
|
||||||
* zlib
|
|
||||||
3. Download [Boost](http://www.boost.org/users/download/)
|
|
||||||
1. Extract the compressed file contents to your (new) `$BOOST_ROOT` location.
|
|
||||||
2. Open a command prompt or shell in the `$BOOST_ROOT`.
|
|
||||||
3. `./bootstrap.bat`
|
|
||||||
4. (Optional, if you also plan to build rippled) `./bjam.exe --toolset=msvc-14.0
|
|
||||||
--build-type=complete variant=debug,release link=static runtime-link=static
|
|
||||||
address-model=64 stage`
|
|
||||||
5. If it is not already there, add your `$BOOST_ROOT` to your environment `$PATH`.
|
|
||||||
|
|
||||||
### MacOS
|
### MacOS
|
||||||
|
|
||||||
@@ -38,47 +23,54 @@ Install these dependencies:
|
|||||||
You'll then need to make doxygen available to your command line. You can
|
You'll then need to make doxygen available to your command line. You can
|
||||||
do this by adding a symbolic link from `/usr/local/bin` to the doxygen
|
do this by adding a symbolic link from `/usr/local/bin` to the doxygen
|
||||||
executable. For example, `$ ln -s /Applications/Doxygen.app/Contents/Resources/doxygen /usr/local/bin/doxygen`
|
executable. For example, `$ ln -s /Applications/Doxygen.app/Contents/Resources/doxygen /usr/local/bin/doxygen`
|
||||||
2. Install [Boost](http://www.boost.org/users/download/)
|
|
||||||
1. Extract the compressed file contents to your (new) `$BOOST_ROOT` location.
|
|
||||||
2. Open a command prompt or shell in the `$BOOST_ROOT`.
|
|
||||||
3. `$ ./bootstrap.bat`
|
|
||||||
4. (Optional, if you also plan to build rippled)
|
|
||||||
`$ ./b2 toolset=clang threading=multi runtime-link=static link=static
|
|
||||||
cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" adress-model=64`
|
|
||||||
5. If it is not already there, add your `$BOOST_ROOT` to your environment
|
|
||||||
`$PATH`. This makes the `b2` command available to the command line.
|
|
||||||
3. That should be all that's required. In OS X 10.11, at least, libxml2 and
|
|
||||||
libxslt come pre-installed.
|
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
1. Install [Docker](https://docs.docker.com/engine/installation/)
|
1. Install doxygen using your package manager OR from source using the links above.
|
||||||
2. Build Docker image. From the rippled root folder:
|
|
||||||
```
|
|
||||||
sudo docker build -t rippled-docs docs/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Setup project submodules
|
### [Optional] Install Plantuml (all platforms)
|
||||||
|
|
||||||
1. Open a shell in your rippled root folder.
|
Doxygen supports the optional use of [plantuml](http://plantuml.com) to
|
||||||
2. `git submodule init`
|
generate diagrams from `@startuml` sections. We don't currently rely on this
|
||||||
3. `git submodule update docs/docca`
|
functionality for docs, so it's largely optional. Requirements:
|
||||||
|
|
||||||
|
1. Download/install a functioning java runtime, if you don't already have one.
|
||||||
|
2. Download [plantuml](http://plantuml.com) from
|
||||||
|
[here](http://sourceforge.net/projects/plantuml/files/plantuml.jar/download).
|
||||||
|
Set a system environment variable named `PLANTUML_JAR` with a value of the fullpath
|
||||||
|
to the file system location of the `plantuml.jar` file you downloaded.
|
||||||
|
|
||||||
## Do it
|
## Do it
|
||||||
|
|
||||||
### Windows & MacOS
|
### all platforms
|
||||||
|
|
||||||
From the rippled root folder:
|
From the rippled root folder:
|
||||||
```
|
```
|
||||||
cd docs
|
cd docs
|
||||||
./makeqbk.sh && b2
|
mkdir -p html_doc
|
||||||
|
doxygen source.dox
|
||||||
```
|
```
|
||||||
The output will be in `docs/html`.
|
The output will be in `docs/html_doc`.
|
||||||
|
|
||||||
### Linux
|
## Docker
|
||||||
|
|
||||||
|
(applicable to all platforms)
|
||||||
|
|
||||||
|
Instead of installing the doxygen tools locally, you can use the provided `Dockerfile` to create
|
||||||
|
an ubuntu based image for running the tools:
|
||||||
|
|
||||||
|
1. Install [Docker](https://docs.docker.com/engine/installation/)
|
||||||
|
2. Build Docker image. From the rippled root folder:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo docker build -t rippled-docs docs/
|
||||||
|
```
|
||||||
|
|
||||||
|
Then to run the image, from the rippled root folder:
|
||||||
|
|
||||||
From the rippled root folder:
|
|
||||||
```
|
```
|
||||||
sudo docker run -v $PWD:/opt/rippled --rm rippled-docs
|
sudo docker run -v $PWD:/opt/rippled --rm rippled-docs
|
||||||
```
|
```
|
||||||
The output will be in `docs/html`.
|
|
||||||
|
The output will be in `docs/html_doc`.
|
||||||
|
|
||||||
|
|||||||
@@ -1,439 +0,0 @@
|
|||||||
<!--
|
|
||||||
BoostBook DTD - development version
|
|
||||||
|
|
||||||
For further information, see: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Boost_Documentation_Format
|
|
||||||
|
|
||||||
Copyright (c) 2002 by Peter Simons <simons@cryp.to>
|
|
||||||
Copyright (c) 2003-2004 by Douglas Gregor <doug.gregor -at- gmail.com>
|
|
||||||
Copyright (c) 2007 by Frank Mori Hess <fmhess@users.sourceforge.net>
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
(See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
The latest stable DTD module is identified by the PUBLIC and SYSTEM identifiers:
|
|
||||||
|
|
||||||
PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
|
|
||||||
SYSTEM "http://www.boost.org/tools/boostbook/dtd/1.1/boostbook.dtd"
|
|
||||||
|
|
||||||
$Revision$
|
|
||||||
$Date$
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--========== Define XInclude features. ==========-->
|
|
||||||
<!-- This is not really integrated into the DTD yet. Needs more
|
|
||||||
research. -->
|
|
||||||
<!--
|
|
||||||
<!ELEMENT xi:include (xi:fallback)?>
|
|
||||||
<!ATTLIST xi:include
|
|
||||||
xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude"
|
|
||||||
href CDATA #REQUIRED
|
|
||||||
parse (xml|text) "xml"
|
|
||||||
encoding CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT xi:fallback ANY>
|
|
||||||
<!ATTLIST xi:fallback
|
|
||||||
xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude">
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!ENTITY % local.common.attrib "last-revision CDATA #IMPLIED">
|
|
||||||
|
|
||||||
<!--========== Define the BoostBook extensions ==========-->
|
|
||||||
<!ENTITY % boost.common.attrib "%local.common.attrib;
|
|
||||||
id CDATA #IMPLIED">
|
|
||||||
|
|
||||||
<!ENTITY % boost.namespace.mix
|
|
||||||
"class|class-specialization|struct|struct-specialization|
|
|
||||||
union|union-specialization|typedef|enum|
|
|
||||||
free-function-group|function|overloaded-function|
|
|
||||||
namespace">
|
|
||||||
|
|
||||||
<!ENTITY % boost.template.mix
|
|
||||||
"template-type-parameter|template-nontype-parameter|template-varargs">
|
|
||||||
|
|
||||||
<!ENTITY % boost.class.members
|
|
||||||
"static-constant|typedef|enum|
|
|
||||||
copy-assignment|constructor|destructor|method-group|
|
|
||||||
method|overloaded-method|data-member|class|class-specialization|struct|
|
|
||||||
struct-specialization|union|union-specialization">
|
|
||||||
|
|
||||||
<!ENTITY % boost.class.mix
|
|
||||||
"%boost.class.members;|free-function-group|function|overloaded-function">
|
|
||||||
|
|
||||||
<!ENTITY % boost.class.content
|
|
||||||
"template?, inherit*, purpose?, description?,
|
|
||||||
(%boost.class.mix;|access)*">
|
|
||||||
|
|
||||||
<!ENTITY % boost.class-specialization.content
|
|
||||||
"template?, specialization?, inherit?, purpose?, description?,
|
|
||||||
(%boost.class.mix;|access)*">
|
|
||||||
|
|
||||||
<!ENTITY % boost.function.semantics
|
|
||||||
"purpose?, description?, requires?, effects?, postconditions?,
|
|
||||||
returns?, throws?, complexity?, notes?, rationale?">
|
|
||||||
|
|
||||||
<!ENTITY % library.content
|
|
||||||
"libraryinfo, (title, ((section|library-reference|testsuite))+)?">
|
|
||||||
|
|
||||||
<!ELEMENT library (%library.content;)>
|
|
||||||
<!ATTLIST library
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
dirname CDATA #REQUIRED
|
|
||||||
html-only CDATA #IMPLIED
|
|
||||||
url CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT boostbook (title, (chapter|library)*)>
|
|
||||||
<!ATTLIST boostbook %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT libraryinfo (author+, copyright*, legalnotice*, librarypurpose, librarycategory*)>
|
|
||||||
<!ATTLIST libraryinfo %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT librarypurpose (#PCDATA|code|ulink|functionname|methodname|classname|macroname|headername|enumname|globalname)*>
|
|
||||||
<!ATTLIST librarypurpose %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT librarycategory (#PCDATA)>
|
|
||||||
<!ATTLIST librarycategory
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT libraryname (#PCDATA)>
|
|
||||||
<!ATTLIST libraryname %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT library-reference ANY>
|
|
||||||
<!ATTLIST library-reference
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT librarylist EMPTY>
|
|
||||||
<!ATTLIST librarylist %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT librarycategorylist (librarycategorydef)*>
|
|
||||||
<!ATTLIST librarycategorylist %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT librarycategorydef (#PCDATA)>
|
|
||||||
<!ATTLIST librarycategorydef
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT header ANY>
|
|
||||||
<!ATTLIST header
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT namespace (%boost.namespace.mix;)*>
|
|
||||||
<!ATTLIST namespace
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT class (%boost.class.content;)>
|
|
||||||
<!ATTLIST class
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT struct (%boost.class.content;)>
|
|
||||||
<!ATTLIST struct
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT union (%boost.class.content;)>
|
|
||||||
<!ATTLIST union
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT class-specialization (%boost.class-specialization.content;)>
|
|
||||||
<!ATTLIST class-specialization
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT struct-specialization (%boost.class-specialization.content;)>
|
|
||||||
<!ATTLIST struct-specialization
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT union-specialization (%boost.class-specialization.content;)>
|
|
||||||
<!ATTLIST union-specialization
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT access (%boost.class.members;)+>
|
|
||||||
<!ATTLIST access
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!--========= C++ Templates =========-->
|
|
||||||
<!ELEMENT template (%boost.template.mix;)*>
|
|
||||||
<!ATTLIST template %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT template-type-parameter (default?, purpose?)>
|
|
||||||
<!ATTLIST template-type-parameter
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
pack CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT template-nontype-parameter (type, default?, purpose?)>
|
|
||||||
<!ATTLIST template-nontype-parameter
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
pack CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT template-varargs EMPTY>
|
|
||||||
<!ATTLIST template-varargs %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT specialization (template-arg)*>
|
|
||||||
<!ATTLIST specialization %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT template-arg ANY>
|
|
||||||
<!ATTLIST template-arg
|
|
||||||
pack CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT default ANY>
|
|
||||||
<!ATTLIST default %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT inherit (type, purpose?)>
|
|
||||||
<!ATTLIST inherit
|
|
||||||
access CDATA #IMPLIED
|
|
||||||
pack CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT purpose ANY>
|
|
||||||
<!ATTLIST purpose %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT description ANY>
|
|
||||||
<!ATTLIST description %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT type ANY>
|
|
||||||
<!ATTLIST type %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT typedef (type, purpose?, description?)>
|
|
||||||
<!ATTLIST typedef
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT enum (enumvalue*, purpose?, description?)>
|
|
||||||
<!ATTLIST enum
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT enumvalue (default?, purpose?, description?)>
|
|
||||||
<!ATTLIST enumvalue
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT static-constant (type, default, purpose?, description?)>
|
|
||||||
<!ATTLIST static-constant
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT data-member (type, purpose?, description?)>
|
|
||||||
<!ATTLIST data-member
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT paramtype ANY>
|
|
||||||
<!ATTLIST paramtype %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT effects ANY>
|
|
||||||
<!ATTLIST effects %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT postconditions ANY>
|
|
||||||
<!ATTLIST postconditions %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT method-group (method|overloaded-method)*>
|
|
||||||
<!ATTLIST method-group
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT constructor (template?, parameter*, %boost.function.semantics;)>
|
|
||||||
<!ATTLIST constructor
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT destructor (%boost.function.semantics;)>
|
|
||||||
<!ATTLIST destructor
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT method (template?, type, parameter*, %boost.function.semantics;)>
|
|
||||||
<!ATTLIST method
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
cv CDATA #IMPLIED
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT function (template?, type, parameter*, %boost.function.semantics;)>
|
|
||||||
<!ATTLIST function
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT overloaded-method (signature*, %boost.function.semantics;)>
|
|
||||||
<!ATTLIST overloaded-method
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT overloaded-function (signature*, %boost.function.semantics;)>
|
|
||||||
<!ATTLIST overloaded-function
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT signature (template?, type, parameter*)>
|
|
||||||
<!ATTLIST signature
|
|
||||||
cv CDATA #IMPLIED
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT requires ANY>
|
|
||||||
<!ATTLIST requires %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT returns ANY>
|
|
||||||
<!ATTLIST returns %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT throws ANY>
|
|
||||||
<!ATTLIST throws %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT complexity ANY>
|
|
||||||
<!ATTLIST complexity %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT notes ANY>
|
|
||||||
<!ATTLIST notes %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT rationale ANY>
|
|
||||||
<!ATTLIST rationale %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT functionname (#PCDATA)>
|
|
||||||
<!ATTLIST functionname
|
|
||||||
alt CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT enumname (#PCDATA)>
|
|
||||||
<!ATTLIST enumname
|
|
||||||
alt CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT macroname (#PCDATA)>
|
|
||||||
<!ATTLIST macroname
|
|
||||||
alt CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT headername (#PCDATA)>
|
|
||||||
<!ATTLIST headername
|
|
||||||
alt CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT globalname (#PCDATA)>
|
|
||||||
<!ATTLIST globalname
|
|
||||||
alt CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT copy-assignment
|
|
||||||
(template?, type?, parameter*, %boost.function.semantics;)>
|
|
||||||
<!ATTLIST copy-assignment
|
|
||||||
cv CDATA #IMPLIED
|
|
||||||
specifiers CDATA #IMPLIED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT free-function-group (function|overloaded-function)*>
|
|
||||||
<!ATTLIST free-function-group
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT precondition ANY>
|
|
||||||
<!ATTLIST precondition %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT code ANY>
|
|
||||||
<!ATTLIST code %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT using-namespace EMPTY>
|
|
||||||
<!ATTLIST using-namespace
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT using-class EMPTY>
|
|
||||||
<!ATTLIST using-class
|
|
||||||
name CDATA #REQUIRED
|
|
||||||
%boost.common.attrib;>
|
|
||||||
|
|
||||||
<!--========== Boost Testsuite Extensions ==========-->
|
|
||||||
<!ENTITY % boost.testsuite.tests
|
|
||||||
"compile-test|link-test|run-test|
|
|
||||||
compile-fail-test|link-fail-test|run-fail-test">
|
|
||||||
<!ENTITY % boost.testsuite.test.content
|
|
||||||
"source*, lib*, requirement*, purpose, if-fails?">
|
|
||||||
|
|
||||||
<!ELEMENT testsuite ((%boost.testsuite.tests;)+)>
|
|
||||||
<!ATTLIST testsuite %boost.common.attrib;>
|
|
||||||
|
|
||||||
<!ELEMENT compile-test (%boost.testsuite.test.content;)>
|
|
||||||
<!ATTLIST compile-test
|
|
||||||
filename CDATA #REQUIRED
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT link-test (%boost.testsuite.test.content;)>
|
|
||||||
<!ATTLIST link-test
|
|
||||||
filename CDATA #REQUIRED
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT run-test (%boost.testsuite.test.content;)>
|
|
||||||
<!ATTLIST run-test
|
|
||||||
filename CDATA #REQUIRED
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT compile-fail-test (%boost.testsuite.test.content;)>
|
|
||||||
<!ATTLIST compile-fail-test
|
|
||||||
filename CDATA #REQUIRED
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT link-fail-test (%boost.testsuite.test.content;)>
|
|
||||||
<!ATTLIST link-fail-test
|
|
||||||
filename CDATA #REQUIRED
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT run-fail-test (%boost.testsuite.test.content;)>
|
|
||||||
<!ATTLIST run-fail-test
|
|
||||||
filename CDATA #REQUIRED
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT source (#PCDATA|snippet)*>
|
|
||||||
|
|
||||||
<!ELEMENT snippet EMPTY>
|
|
||||||
<!ATTLIST snippet
|
|
||||||
name CDATA #REQUIRED>
|
|
||||||
|
|
||||||
<!ELEMENT lib (#PCDATA)>
|
|
||||||
|
|
||||||
<!ELEMENT requirement (#PCDATA)>
|
|
||||||
<!ATTLIST requirement
|
|
||||||
name CDATA #REQUIRED>
|
|
||||||
|
|
||||||
<!ELEMENT if-fails ANY>
|
|
||||||
|
|
||||||
<!ELEMENT parameter (paramtype, default?, description?)>
|
|
||||||
<!ATTLIST parameter
|
|
||||||
name CDATA #IMPLIED
|
|
||||||
pack CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT programlisting ANY>
|
|
||||||
<!ATTLIST programlisting
|
|
||||||
name CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!--========== Customize the DocBook DTD ==========-->
|
|
||||||
<!ENTITY % local.tech.char.class "|functionname|libraryname|enumname|headername|macroname|code">
|
|
||||||
<!ENTITY % local.para.class
|
|
||||||
"|using-namespace|using-class|librarylist|librarycategorylist">
|
|
||||||
<!ENTITY % local.descobj.class "|libraryinfo">
|
|
||||||
<!ENTITY % local.classname.attrib "alt CDATA #IMPLIED">
|
|
||||||
<!ENTITY % local.methodname.attrib "alt CDATA #IMPLIED">
|
|
||||||
<!ENTITY % local.refentry.class "|library-reference|testsuite">
|
|
||||||
<!ENTITY % local.title.char.mix "">
|
|
||||||
<!ENTITY % programlisting.module "IGNORE">
|
|
||||||
<!ENTITY % parameter.module "IGNORE">
|
|
||||||
<!ENTITY % function.module "IGNORE">
|
|
||||||
<!ENTITY % type.module "IGNORE">
|
|
||||||
|
|
||||||
<!--========== Import DocBook DTD ==========-->
|
|
||||||
<!ENTITY % DocBook PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
|
||||||
|
|
||||||
%DocBook;
|
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
[section Consensus and Validation]
|
# Consensus and Validation
|
||||||
|
|
||||||
[*This section is a work in progress!!]
|
**This section is a work in progress!!**
|
||||||
|
|
||||||
Consensus is the task of reaching agreement within a distributed system in the
|
Consensus is the task of reaching agreement within a distributed system in the
|
||||||
presence of faulty or even malicious participants. This document outlines the
|
presence of faulty or even malicious participants. This document outlines the
|
||||||
[@https://ripple.com/files/ripple/consensus/whitepaper.pdf Ripple Consensus
|
[Ripple Consensus Algorithm](https://ripple.com/files/ripple/consensus/whitepaper.pdf)
|
||||||
Algorithm] as implemented in [@https://github.com/ripple/rippled rippled], but
|
as implemented in [rippled](https://github.com/ripple/rippled), but
|
||||||
focuses on its utility as a generic consensus algorithm independent of the
|
focuses on its utility as a generic consensus algorithm independent of the
|
||||||
detailed mechanics of the Ripple Consensus Ledger. Most notably, the algorithm
|
detailed mechanics of the Ripple Consensus Ledger. Most notably, the algorithm
|
||||||
does not require fully synchronous communication between all nodes in the
|
does not require fully synchronous communication between all nodes in the
|
||||||
network, or even a fixed network topology, but instead achieves consensus via
|
network, or even a fixed network topology, but instead achieves consensus via
|
||||||
collectively trusted subnetworks.
|
collectively trusted subnetworks.
|
||||||
|
|
||||||
[heading Distributed Agreement]
|
## Distributed Agreement
|
||||||
|
|
||||||
A challenge for distributed systems is reaching agreement on changes in shared
|
A challenge for distributed systems is reaching agreement on changes in shared
|
||||||
state. For the Ripple network, the shared state is the current ledger--account
|
state. For the Ripple network, the shared state is the current ledger--account
|
||||||
@@ -20,7 +20,7 @@ information, account balances, order books and other financial data. We will
|
|||||||
refer to shared distributed state as a /ledger/ throughout the remainder of this
|
refer to shared distributed state as a /ledger/ throughout the remainder of this
|
||||||
document.
|
document.
|
||||||
|
|
||||||
[$images/consensus/ledger_chain.png [width 50%] [height 50%] ]
|

|
||||||
|
|
||||||
As shown above, new ledgers are made by applying a set of transactions to the
|
As shown above, new ledgers are made by applying a set of transactions to the
|
||||||
prior ledger. For the Ripple network, transactions include payments,
|
prior ledger. For the Ripple network, transactions include payments,
|
||||||
@@ -33,14 +33,14 @@ the set of transactions to include, the order to apply those transactions, and
|
|||||||
even the resulting ledger after applying the transactions. This is even more
|
even the resulting ledger after applying the transactions. This is even more
|
||||||
difficult when some participants are faulty or malicious.
|
difficult when some participants are faulty or malicious.
|
||||||
|
|
||||||
The Ripple network is a decentralized and _trust-full_ network. Anyone is free
|
The Ripple network is a decentralized and **trust-full** network. Anyone is free
|
||||||
to join and participants are free to choose a subset of peers that are
|
to join and participants are free to choose a subset of peers that are
|
||||||
collectively trusted to not collude in an attempt to defraud the participant.
|
collectively trusted to not collude in an attempt to defraud the participant.
|
||||||
Leveraging this network of trust, the Ripple algorithm has two main components.
|
Leveraging this network of trust, the Ripple algorithm has two main components.
|
||||||
|
|
||||||
* /Consensus/ in which network participants agree on the transactions to apply
|
* *Consensus* in which network participants agree on the transactions to apply
|
||||||
to a prior ledger, based on the positions of their chosen peers.
|
to a prior ledger, based on the positions of their chosen peers.
|
||||||
* /Validation/ in which network participants agree on what ledger was
|
* *Validation* in which network participants agree on what ledger was
|
||||||
generated, based on the ledgers generated by chosen peers.
|
generated, based on the ledgers generated by chosen peers.
|
||||||
|
|
||||||
These phases are continually repeated to process transactions submitted to the
|
These phases are continually repeated to process transactions submitted to the
|
||||||
@@ -50,46 +50,46 @@ links between ledgers point backward to the parent. Also note the alternate
|
|||||||
Ledger 2 that was generated by some participants, but which failed validation
|
Ledger 2 that was generated by some participants, but which failed validation
|
||||||
and was abandoned.
|
and was abandoned.
|
||||||
|
|
||||||
[$images/consensus/block_chain.png]
|

|
||||||
|
|
||||||
The remainder of this section describes the Consensus and Validation algorithms
|
The remainder of this section describes the Consensus and Validation algorithms
|
||||||
in more detail and is meant as a companion guide to understanding the generic
|
in more detail and is meant as a companion guide to understanding the generic
|
||||||
implementation in =rippled=. The document *does not* discuss correctness,
|
implementation in `rippled`. The document **does not** discuss correctness,
|
||||||
fault-tolerance or liveness properties of the algorithms or the full details of
|
fault-tolerance or liveness properties of the algorithms or the full details of
|
||||||
how they integrate within =rippled= to support the Ripple Consensus Ledger.
|
how they integrate within `rippled` to support the Ripple Consensus Ledger.
|
||||||
|
|
||||||
[section Consensus Overview]
|
## Consensus Overview
|
||||||
|
|
||||||
[heading Definitions]
|
### Definitions
|
||||||
|
|
||||||
* The /ledger/ is the shared distributed state. Each ledger has a unique ID to
|
* The *ledger* is the shared distributed state. Each ledger has a unique ID to
|
||||||
distinguish it from all other ledgers. During consensus, the /previous/,
|
distinguish it from all other ledgers. During consensus, the *previous*,
|
||||||
/prior/ or /last-closed/ ledger is the most recent ledger seen by consensus
|
*prior* or *last-closed* ledger is the most recent ledger seen by consensus
|
||||||
and is the basis upon which it will build the next ledger.
|
and is the basis upon which it will build the next ledger.
|
||||||
* A /transaction/ is an instruction for an atomic change in the ledger state. A
|
* A *transaction* is an instruction for an atomic change in the ledger state. A
|
||||||
unique ID distinguishes a transaction from other transactions.
|
unique ID distinguishes a transaction from other transactions.
|
||||||
* A /transaction set/ is a set of transactions under consideration by consensus.
|
* A *transaction set* is a set of transactions under consideration by consensus.
|
||||||
The goal of consensus is to reach agreement on this set. The generic
|
The goal of consensus is to reach agreement on this set. The generic
|
||||||
consensus algorithm does not rely on an ordering of transactions within the
|
consensus algorithm does not rely on an ordering of transactions within the
|
||||||
set, nor does it specify how to apply a transaction set to a ledger to
|
set, nor does it specify how to apply a transaction set to a ledger to
|
||||||
generate a new ledger. A unique ID distinguishes a set of transactions from
|
generate a new ledger. A unique ID distinguishes a set of transactions from
|
||||||
all other sets of transactions.
|
all other sets of transactions.
|
||||||
* A /node/ is one of the distributed actors running the consensus algorithm. It
|
* A *node* is one of the distributed actors running the consensus algorithm. It
|
||||||
has a unique ID to distinguish it from all other nodes.
|
has a unique ID to distinguish it from all other nodes.
|
||||||
* A /peer/ of a node is another node that it has chosen to follow and which it
|
* A *peer* of a node is another node that it has chosen to follow and which it
|
||||||
believes will not collude with other chosen peers. The choice of peers is not
|
believes will not collude with other chosen peers. The choice of peers is not
|
||||||
symmetric, since participants can decide on their chosen sets independently.
|
symmetric, since participants can decide on their chosen sets independently.
|
||||||
* A /position/ is the current belief of the next ledger's transaction set and
|
* A /position/ is the current belief of the next ledger's transaction set and
|
||||||
close time. Position can refer to the node's own position or the position of a
|
close time. Position can refer to the node's own position or the position of a
|
||||||
peer.
|
peer.
|
||||||
* A /proposal/ is one of a sequence of positions a node shares during consensus.
|
* A *proposal* is one of a sequence of positions a node shares during consensus.
|
||||||
An initial proposal contains the starting position taken by a node before it
|
An initial proposal contains the starting position taken by a node before it
|
||||||
considers any peer positions. If a node subsequently updates its position in
|
considers any peer positions. If a node subsequently updates its position in
|
||||||
response to its peers, it will issue an updated proposal. A proposal is
|
response to its peers, it will issue an updated proposal. A proposal is
|
||||||
uniquely identified by the ID of the proposing node, the ID of the position
|
uniquely identified by the ID of the proposing node, the ID of the position
|
||||||
taken, the ID of the prior ledger the proposal is for, and the sequence number
|
taken, the ID of the prior ledger the proposal is for, and the sequence number
|
||||||
of the proposal.
|
of the proposal.
|
||||||
* A /dispute/ is a transaction that is either not part of a node's position or
|
* A *dispute* is a transaction that is either not part of a node's position or
|
||||||
not in a peer's position. During consensus, the node will add or remove
|
not in a peer's position. During consensus, the node will add or remove
|
||||||
disputed transactions from its position based on that transaction's support
|
disputed transactions from its position based on that transaction's support
|
||||||
amongst its peers.
|
amongst its peers.
|
||||||
@@ -101,61 +101,61 @@ contain the ID of the position of a peer. Since many peers likely have the same
|
|||||||
position, this reduces the need to send the full transaction set multiple times.
|
position, this reduces the need to send the full transaction set multiple times.
|
||||||
Instead, a node can request the transaction set from the network if necessary.
|
Instead, a node can request the transaction set from the network if necessary.
|
||||||
|
|
||||||
[heading Overview ]
|
### Overview
|
||||||
[$images/consensus/consensus_overview.png [width 50%] [height 50%] ]
|
|
||||||
|

|
||||||
|
|
||||||
The diagram above is an overview of the consensus process from the perspective
|
The diagram above is an overview of the consensus process from the perspective
|
||||||
of a single participant. Recall that during a single consensus round, a node is
|
of a single participant. Recall that during a single consensus round, a node is
|
||||||
trying to agree with its peers on which transactions to apply to its prior
|
trying to agree with its peers on which transactions to apply to its prior
|
||||||
ledger when generating the next ledger. It also attempts to agree on the
|
ledger when generating the next ledger. It also attempts to agree on the
|
||||||
[link effective_close_time network time when the ledger closed]. There are
|
[network time when the ledger closed](#effective_close_time). There are
|
||||||
3 main phases to a consensus round:
|
3 main phases to a consensus round:
|
||||||
|
|
||||||
* A call to =startRound= places the node in the =Open= phase. In this phase,
|
* A call to `startRound` places the node in the `Open` phase. In this phase,
|
||||||
the node is waiting for transactions to include in its open ledger.
|
the node is waiting for transactions to include in its open ledger.
|
||||||
* At some point, the node will =Close= the open ledger and transition to the
|
* At some point, the node will `Close` the open ledger and transition to the
|
||||||
=Establish= phase. In this phase, the node shares/receives peer proposals on
|
`Establish` phase. In this phase, the node shares/receives peer proposals on
|
||||||
which transactions should be accepted in the closed ledger.
|
which transactions should be accepted in the closed ledger.
|
||||||
* At some point, the node determines it has reached consensus with its peers on
|
* At some point, the node determines it has reached consensus with its peers on
|
||||||
which transactions to include. It transitions to the =Accept= phase. In this
|
which transactions to include. It transitions to the `Accept` phase. In this
|
||||||
phase, the node works on applying the transactions to the prior ledger to
|
phase, the node works on applying the transactions to the prior ledger to
|
||||||
generate a new closed ledger. Once the new ledger is completed, the node shares
|
generate a new closed ledger. Once the new ledger is completed, the node shares
|
||||||
the validated ledger hash with the network and makes a call to =startRound= to
|
the validated ledger hash with the network and makes a call to `startRound` to
|
||||||
start the cycle again for the next ledger.
|
start the cycle again for the next ledger.
|
||||||
|
|
||||||
Throughout, a heartbeat timer calls =timerEntry= at a regular frequency to drive
|
Throughout, a heartbeat timer calls `timerEntry` at a regular frequency to drive
|
||||||
the process forward. Although the =startRound= call occurs at arbitrary times
|
the process forward. Although the `startRound` call occurs at arbitrary times
|
||||||
based on when the initial round began and the time it takes to apply
|
based on when the initial round began and the time it takes to apply
|
||||||
transactions, the transitions from =Open= to =Establish= and =Establish= to
|
transactions, the transitions from `Open` to `Establish` and `Establish` to
|
||||||
=Accept= only occur during calls to =timerEntry=. Similarly, transactions can
|
`Accept` only occur during calls to `timerEntry`. Similarly, transactions can
|
||||||
arrive at arbitrary times, independent of the heartbeat timer. Transactions
|
arrive at arbitrary times, independent of the heartbeat timer. Transactions
|
||||||
received after the =Open= to =Close= transition and not part of peer proposals
|
received after the `Open` to `Close` transition and not part of peer proposals
|
||||||
won't be considered until the next consensus round. They are represented above
|
won't be considered until the next consensus round. They are represented above
|
||||||
by the light green triangles.
|
by the light green triangles.
|
||||||
|
|
||||||
Peer proposals are issued by a node during a =timerEntry= call, but since peers
|
Peer proposals are issued by a node during a `timerEntry` call, but since peers
|
||||||
do not synchronize =timerEntry= calls, they are received by other peers at
|
do not synchronize `timerEntry` calls, they are received by other peers at
|
||||||
arbitrary times. Peer proposals are only considered if received prior to the
|
arbitrary times. Peer proposals are only considered if received prior to the
|
||||||
=Establish= to =Accept= transition, and only if the peer is working on the same
|
`Establish` to `Accept` transition, and only if the peer is working on the same
|
||||||
prior ledger. Peer proposals received after consensus is reached will not be
|
prior ledger. Peer proposals received after consensus is reached will not be
|
||||||
meaningful and are represented above by the circle with the X in it. Only
|
meaningful and are represented above by the circle with the X in it. Only
|
||||||
proposals from chosen peers are considered.
|
proposals from chosen peers are considered.
|
||||||
|
|
||||||
[#effective_close_time]
|
### Effective Close Time ### {#effective_close_time}
|
||||||
[heading Effective Close Time]
|
|
||||||
|
|
||||||
In addition to agreeing on a transaction set, each consensus round tries to
|
In addition to agreeing on a transaction set, each consensus round tries to
|
||||||
agree on the time the ledger closed. Each node calculates its own close time
|
agree on the time the ledger closed. Each node calculates its own close time
|
||||||
when it closes the open ledger. This exact close time is rounded to the nearest
|
when it closes the open ledger. This exact close time is rounded to the nearest
|
||||||
multiple of the current /effective close time resolution/. It is this
|
multiple of the current *effective close time resolution*. It is this
|
||||||
/effective close time/ that nodes seek to agree on. This allows servers to
|
*effective close time* that nodes seek to agree on. This allows servers to
|
||||||
derive a common time for a ledger without the need for perfectly synchronized
|
derive a common time for a ledger without the need for perfectly synchronized
|
||||||
clocks. As depicted below, the 3 pink arrows represent exact close times from 3
|
clocks. As depicted below, the 3 pink arrows represent exact close times from 3
|
||||||
consensus nodes that round to the same effective close time given the current
|
consensus nodes that round to the same effective close time given the current
|
||||||
resolution. The purple arrow represents a peer whose estimate rounds to a
|
resolution. The purple arrow represents a peer whose estimate rounds to a
|
||||||
different effective close time given the current resolution.
|
different effective close time given the current resolution.
|
||||||
|
|
||||||
[$images/consensus/EffCloseTime.png]
|

|
||||||
|
|
||||||
The effective close time is part of the node's position and is shared with peers
|
The effective close time is part of the node's position and is shared with peers
|
||||||
in its proposals. Just like the position on the consensus transaction set, a
|
in its proposals. Just like the position on the consensus transaction set, a
|
||||||
@@ -168,14 +168,14 @@ subsequent consensus rounds if nodes are unable to reach consensus on an
|
|||||||
effective close time and increasing (finer) resolution if nodes consistently
|
effective close time and increasing (finer) resolution if nodes consistently
|
||||||
reach close time consensus.
|
reach close time consensus.
|
||||||
|
|
||||||
[heading Modes]
|
### Modes
|
||||||
|
|
||||||
Internally, a node operates under one of the following consensus modes. Either
|
Internally, a node operates under one of the following consensus modes. Either
|
||||||
of the first two modes may be chosen when a consensus round starts.
|
of the first two modes may be chosen when a consensus round starts.
|
||||||
|
|
||||||
* /Proposing/ indicates the node is a full-fledged consensus participant. It
|
* *Proposing* indicates the node is a full-fledged consensus participant. It
|
||||||
takes on positions and sends proposals to its peers.
|
takes on positions and sends proposals to its peers.
|
||||||
* /Observing/ indicates the node is a passive consensus participant. It
|
* *Observing* indicates the node is a passive consensus participant. It
|
||||||
maintains a position internally, but does not propose that position to its
|
maintains a position internally, but does not propose that position to its
|
||||||
peers. Instead, it receives peer proposals and updates its position
|
peers. Instead, it receives peer proposals and updates its position
|
||||||
to track the majority of its peers. This may be preferred if the node is only
|
to track the majority of its peers. This may be preferred if the node is only
|
||||||
@@ -184,21 +184,21 @@ of the first two modes may be chosen when a consensus round starts.
|
|||||||
|
|
||||||
The other two modes are set internally during the consensus round when the node
|
The other two modes are set internally during the consensus round when the node
|
||||||
believes it is no longer working on the dominant ledger chain based on peer
|
believes it is no longer working on the dominant ledger chain based on peer
|
||||||
validations. It checks this on every call to =timerEntry=.
|
validations. It checks this on every call to `timerEntry`.
|
||||||
|
|
||||||
* /Wrong Ledger/ indicates the node is not working on the correct prior ledger
|
* *Wrong Ledger* indicates the node is not working on the correct prior ledger
|
||||||
and does not have it available. It requests that ledger from the network, but
|
and does not have it available. It requests that ledger from the network, but
|
||||||
continues to work towards consensus this round while waiting. If it had been
|
continues to work towards consensus this round while waiting. If it had been
|
||||||
/proposing/, it will send a special "bowout" proposal to its peers to indicate
|
*proposing*, it will send a special "bowout" proposal to its peers to indicate
|
||||||
its change in mode for the rest of this round. For the duration of the round,
|
its change in mode for the rest of this round. For the duration of the round,
|
||||||
it defers to peer positions for determining the consensus outcome as if it
|
it defers to peer positions for determining the consensus outcome as if it
|
||||||
were just /observing/.
|
were just *observing*.
|
||||||
* /Switch Ledger/ indicates that the node has acquired the correct prior ledger
|
* *Switch Ledger* indicates that the node has acquired the correct prior ledger
|
||||||
from the network. Although it now has the correct prior ledger, the fact that
|
from the network. Although it now has the correct prior ledger, the fact that
|
||||||
it had the wrong one at some point during this round means it is likely behind
|
it had the wrong one at some point during this round means it is likely behind
|
||||||
and should defer to peer positions for determining the consensus outcome.
|
and should defer to peer positions for determining the consensus outcome.
|
||||||
|
|
||||||
[$images/consensus/consensus_modes.png]
|

|
||||||
|
|
||||||
Once either wrong ledger or switch ledger are reached, the node cannot
|
Once either wrong ledger or switch ledger are reached, the node cannot
|
||||||
return to proposing or observing until the next consensus round. However,
|
return to proposing or observing until the next consensus round. However,
|
||||||
@@ -212,49 +212,49 @@ time to share over the network, whereas the smaller ID could be shared in a peer
|
|||||||
validation much more quickly. Distinguishing the two states allows the node to
|
validation much more quickly. Distinguishing the two states allows the node to
|
||||||
decide how best to generate the next ledger once it declares consensus.
|
decide how best to generate the next ledger once it declares consensus.
|
||||||
|
|
||||||
[heading Phases]
|
### Phases
|
||||||
|
|
||||||
As depicted in the overview diagram, consensus is best viewed as a progression
|
As depicted in the overview diagram, consensus is best viewed as a progression
|
||||||
through 3 phases. There are 4 public methods of the generic consensus algorithm
|
through 3 phases. There are 4 public methods of the generic consensus algorithm
|
||||||
that determine this progression
|
that determine this progression
|
||||||
|
|
||||||
* =startRound= begins a consensus round.
|
* `startRound` begins a consensus round.
|
||||||
* =timerEntry= is called at a regular frequency (=LEDGER_MIN_CLOSE=) and is the
|
* `timerEntry` is called at a regular frequency (`LEDGER_MIN_CLOSE`) and is the
|
||||||
only call to consensus that can change the phase from =Open= to =Establish=
|
only call to consensus that can change the phase from `Open` to `Establish`
|
||||||
or =Accept=.
|
or `Accept`.
|
||||||
* =peerProposal= is called whenever a peer proposal is received and is what
|
* `peerProposal` is called whenever a peer proposal is received and is what
|
||||||
allows a node to update its position in a subsequent =timerEntry= call.
|
allows a node to update its position in a subsequent `timerEntry` call.
|
||||||
* =gotTxSet= is called when a transaction set is received from the network. This
|
* `gotTxSet` is called when a transaction set is received from the network. This
|
||||||
is typically in response to a prior request from the node to acquire the
|
is typically in response to a prior request from the node to acquire the
|
||||||
transaction set corresponding to a disagreeing peer's position.
|
transaction set corresponding to a disagreeing peer's position.
|
||||||
|
|
||||||
The following subsections describe each consensus phase in more detail and what
|
The following subsections describe each consensus phase in more detail and what
|
||||||
actions are taken in response to these calls.
|
actions are taken in response to these calls.
|
||||||
|
|
||||||
[h6 Open]
|
#### Open
|
||||||
|
|
||||||
The =Open= phase is a quiescent period to allow transactions to build up in the
|
The `Open` phase is a quiescent period to allow transactions to build up in the
|
||||||
node's open ledger. The duration is a trade-off between latency and throughput.
|
node's open ledger. The duration is a trade-off between latency and throughput.
|
||||||
A shorter window reduces the latency to generating the next ledger, but also
|
A shorter window reduces the latency to generating the next ledger, but also
|
||||||
reduces transaction throughput due to fewer transactions accepted into the
|
reduces transaction throughput due to fewer transactions accepted into the
|
||||||
ledger.
|
ledger.
|
||||||
|
|
||||||
A call to =startRound= would forcibly begin the next consensus round, skipping
|
A call to `startRound` would forcibly begin the next consensus round, skipping
|
||||||
completion of the current round. This is not expected during normal operation.
|
completion of the current round. This is not expected during normal operation.
|
||||||
Calls to =peerProposal= or =gotTxSet= simply store the proposal or transaction
|
Calls to `peerProposal` or `gotTxSet` simply store the proposal or transaction
|
||||||
set for use in the coming =Establish= phase.
|
set for use in the coming `Establish` phase.
|
||||||
|
|
||||||
A call to =timerEntry= first checks that the node is working on the correct
|
A call to `timerEntry` first checks that the node is working on the correct
|
||||||
prior ledger. If not, it will update the mode and request the correct ledger.
|
prior ledger. If not, it will update the mode and request the correct ledger.
|
||||||
Otherwise, the node checks whether to switch to the =Establish= phase and close
|
Otherwise, the node checks whether to switch to the `Establish` phase and close
|
||||||
the ledger.
|
the ledger.
|
||||||
|
|
||||||
['Ledger Close]
|
##### Ledger Close
|
||||||
|
|
||||||
Under normal circumstances, the open ledger period ends when one of the following
|
Under normal circumstances, the open ledger period ends when one of the following
|
||||||
is true
|
is true
|
||||||
|
|
||||||
* if there are transactions in the open ledger and more than =LEDGER_MIN_CLOSE=
|
* if there are transactions in the open ledger and more than `LEDGER_MIN_CLOSE`
|
||||||
have elapsed. This is the typical behavior.
|
have elapsed. This is the typical behavior.
|
||||||
* if there are no open transactions and a suitably longer idle interval has
|
* if there are no open transactions and a suitably longer idle interval has
|
||||||
elapsed. This increases the opportunity to get some transaction into
|
elapsed. This increases the opportunity to get some transaction into
|
||||||
@@ -275,48 +275,48 @@ transaction.
|
|||||||
In the example below, we suppose our node has closed with transactions 1,2 and 3. It creates disputes
|
In the example below, we suppose our node has closed with transactions 1,2 and 3. It creates disputes
|
||||||
for transactions 2,3 and 4, since at least one peer position differs on each.
|
for transactions 2,3 and 4, since at least one peer position differs on each.
|
||||||
|
|
||||||
[#disputes_image]
|
##### disputes ##### {#disputes_image}
|
||||||
[$images/consensus/disputes.png [width 20%] [height 20%]]
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
[h6 Establish]
|
#### Establish
|
||||||
|
|
||||||
The establish phase is the active period of consensus in which the node
|
The establish phase is the active period of consensus in which the node
|
||||||
exchanges proposals with peers in an attempt to reach agreement on the consensus
|
exchanges proposals with peers in an attempt to reach agreement on the consensus
|
||||||
transactions and effective close time.
|
transactions and effective close time.
|
||||||
|
|
||||||
A call to =startRound= would forcibly begin the next consensus round, skipping
|
A call to `startRound` would forcibly begin the next consensus round, skipping
|
||||||
completion of the current round. This is not expected during normal operation.
|
completion of the current round. This is not expected during normal operation.
|
||||||
Calls to =peerProposal= or =gotTxSet= that reflect new positions will generate
|
Calls to `peerProposal` or `gotTxSet` that reflect new positions will generate
|
||||||
disputed transactions for any new disagreements and will update the peer's vote
|
disputed transactions for any new disagreements and will update the peer's vote
|
||||||
for all disputed transactions.
|
for all disputed transactions.
|
||||||
|
|
||||||
A call to =timerEntry= first checks that the node is working from the correct
|
A call to `timerEntry` first checks that the node is working from the correct
|
||||||
prior ledger. If not, the node will update the mode and request the correct
|
prior ledger. If not, the node will update the mode and request the correct
|
||||||
ledger. Otherwise, the node updates the node's position and considers whether
|
ledger. Otherwise, the node updates the node's position and considers whether
|
||||||
to switch to the =Accepted= phase and declare consensus reached. However, at
|
to switch to the `Accepted` phase and declare consensus reached. However, at
|
||||||
least =LEDGER_MIN_CONSENSUS= time must have elapsed before doing either. This
|
least `LEDGER_MIN_CONSENSUS` time must have elapsed before doing either. This
|
||||||
allows peers an opportunity to take an initial position and share it.
|
allows peers an opportunity to take an initial position and share it.
|
||||||
|
|
||||||
['Update Position]
|
##### Update Position
|
||||||
|
|
||||||
In order to achieve consensus, the node is looking for a transaction set that is
|
In order to achieve consensus, the node is looking for a transaction set that is
|
||||||
supported by a super-majority of peers. The node works towards this set by
|
supported by a super-majority of peers. The node works towards this set by
|
||||||
adding or removing disputed transactions from its position based on an
|
adding or removing disputed transactions from its position based on an
|
||||||
increasing threshold for inclusion.
|
increasing threshold for inclusion.
|
||||||
|
|
||||||
[$images/consensus/threshold.png [width 50%] [height 50%]]
|

|
||||||
|
|
||||||
By starting with a lower threshold, a node initially allows a wide set of
|
By starting with a lower threshold, a node initially allows a wide set of
|
||||||
transactions into its position. If the establish round continues and the node is
|
transactions into its position. If the establish round continues and the node is
|
||||||
"stuck", a higher threshold can focus on accepting transactions with the most
|
"stuck", a higher threshold can focus on accepting transactions with the most
|
||||||
support. The constants that define the thresholds and durations at which the
|
support. The constants that define the thresholds and durations at which the
|
||||||
thresholds change are given by `AV_XXX_CONSENSUS_PCT` and
|
thresholds change are given by `AV_XXX_CONSENSUS_PCT` and
|
||||||
`AV_XXX_CONSENSUS_TIME` respectively, where =XXX= is =INIT=,=MID=,=LATE= and
|
`AV_XXX_CONSENSUS_TIME` respectively, where `XXX` is `INIT`,`MID`,`LATE` and
|
||||||
=STUCK=. The effective close time position is updated using the same
|
`STUCK`. The effective close time position is updated using the same
|
||||||
thresholds.
|
thresholds.
|
||||||
|
|
||||||
Given the [link disputes_image example disputes above] and an initial threshold
|
Given the [example disputes above](#disputes_image) and an initial threshold
|
||||||
of 50%, our node would retain its position since transaction 1 was not in
|
of 50%, our node would retain its position since transaction 1 was not in
|
||||||
dispute and transactions 2 and 3 have 75% support. Since its position did not
|
dispute and transactions 2 and 3 have 75% support. Since its position did not
|
||||||
change, it would not need to send a new proposal to peers. Peer C would not
|
change, it would not need to send a new proposal to peers. Peer C would not
|
||||||
@@ -333,7 +333,7 @@ Lastly, if our node were not in the proposing mode, it would not include its own
|
|||||||
vote and just take the majority (>50%) position of its peers. In this example,
|
vote and just take the majority (>50%) position of its peers. In this example,
|
||||||
our node would maintain its position of transactions 1, 2 and 3.
|
our node would maintain its position of transactions 1, 2 and 3.
|
||||||
|
|
||||||
['Checking Consensus]
|
##### Checking Consensus
|
||||||
|
|
||||||
After updating its position, the node checks for supermajority agreement with
|
After updating its position, the node checks for supermajority agreement with
|
||||||
its peers on its current position. This agreement is of the exact transaction
|
its peers on its current position. This agreement is of the exact transaction
|
||||||
@@ -347,11 +347,11 @@ Consensus is declared when the following 3 clauses are true:
|
|||||||
* `LEDGER_MIN_CONSENSUS` time has elapsed in the establish phase
|
* `LEDGER_MIN_CONSENSUS` time has elapsed in the establish phase
|
||||||
* At least 75% of the prior round proposers have proposed OR this establish
|
* At least 75% of the prior round proposers have proposed OR this establish
|
||||||
phase is `LEDGER_MIN_CONSENSUS` longer than the last round's establish phase
|
phase is `LEDGER_MIN_CONSENSUS` longer than the last round's establish phase
|
||||||
* =minimumConsensusPercentage= of ourself and our peers share the same position
|
* `minimumConsensusPercentage` of ourself and our peers share the same position
|
||||||
|
|
||||||
The middle condition ensures slower peers have a chance to share positions, but
|
The middle condition ensures slower peers have a chance to share positions, but
|
||||||
prevents waiting too long on peers that have disconnected. Additionally, a node
|
prevents waiting too long on peers that have disconnected. Additionally, a node
|
||||||
can declare that consensus has moved on if =minimumConsensusPercentage= peers
|
can declare that consensus has moved on if `minimumConsensusPercentage` peers
|
||||||
have sent validations and moved on to the next ledger. This outcome indicates
|
have sent validations and moved on to the next ledger. This outcome indicates
|
||||||
the node has fallen behind its peers and needs to catch up.
|
the node has fallen behind its peers and needs to catch up.
|
||||||
|
|
||||||
@@ -359,45 +359,43 @@ If a node is not proposing, it does not include its own position when
|
|||||||
calculating the percent of agreeing participants but otherwise follows the above
|
calculating the percent of agreeing participants but otherwise follows the above
|
||||||
logic.
|
logic.
|
||||||
|
|
||||||
['Accepting Consensus]
|
##### Accepting Consensus
|
||||||
|
|
||||||
Once consensus is reached (or moved on), the node switches to the =Accept= phase
|
Once consensus is reached (or moved on), the node switches to the `Accept` phase
|
||||||
and signals to the implementing code that the round is complete. That code is
|
and signals to the implementing code that the round is complete. That code is
|
||||||
responsible for using the consensus transaction set to generate the next ledger
|
responsible for using the consensus transaction set to generate the next ledger
|
||||||
and calling =startRound= to begin the next round. The implementation has total
|
and calling `startRound` to begin the next round. The implementation has total
|
||||||
freedom on ordering transactions, deciding what to do if consensus moved on,
|
freedom on ordering transactions, deciding what to do if consensus moved on,
|
||||||
determining whether to retry or abandon local transactions that did not make the
|
determining whether to retry or abandon local transactions that did not make the
|
||||||
consensus set and updating any internal state based on the consensus progress.
|
consensus set and updating any internal state based on the consensus progress.
|
||||||
|
|
||||||
|
#### Accept
|
||||||
|
|
||||||
[h6 Accept]
|
The `Accept` phase is the terminal phase of the consensus algorithm. Calls to
|
||||||
|
`timerEntry`, `peerProposal` and `gotTxSet` will not change the internal
|
||||||
The =Accept= phase is the terminal phase of the consensus algorithm. Calls to
|
|
||||||
=timerEntry=, =peerProposal= and =gotTxSet= will not change the internal
|
|
||||||
consensus state while in the accept phase. The expectation is that the
|
consensus state while in the accept phase. The expectation is that the
|
||||||
application specific code is working to generate the new ledger based on the
|
application specific code is working to generate the new ledger based on the
|
||||||
consensus outcome. Once complete, that code should make a call to =startRound=
|
consensus outcome. Once complete, that code should make a call to `startRound`
|
||||||
to kick off the next consensus round. The =startRound= call includes the new
|
to kick off the next consensus round. The `startRound` call includes the new
|
||||||
prior ledger, prior ledger ID and whether the round should begin in the
|
prior ledger, prior ledger ID and whether the round should begin in the
|
||||||
proposing or observing mode. After setting some initial state, the phase
|
proposing or observing mode. After setting some initial state, the phase
|
||||||
transitions to =Open=. The node will also check if the provided prior ledger
|
transitions to `Open`. The node will also check if the provided prior ledger
|
||||||
and ID are correct, updating the mode and requesting the proper ledger from the
|
and ID are correct, updating the mode and requesting the proper ledger from the
|
||||||
network if necessary.
|
network if necessary.
|
||||||
|
|
||||||
[endsect] [/Consensus Overview]
|
## Consensus Type Requirements
|
||||||
|
|
||||||
[section Consensus Type Requirements]
|
|
||||||
|
|
||||||
The consensus type requirements are given below as minimal implementation stubs.
|
The consensus type requirements are given below as minimal implementation stubs.
|
||||||
Actual implementations would augment these stubs with members appropriate for
|
Actual implementations would augment these stubs with members appropriate for
|
||||||
managing the details of transactions and ledgers within the larger application
|
managing the details of transactions and ledgers within the larger application
|
||||||
framework.
|
framework.
|
||||||
|
|
||||||
[heading Transaction]
|
### Transaction
|
||||||
The transaction type =Tx= encapsulates a single transaction under consideration
|
|
||||||
|
The transaction type `Tx` encapsulates a single transaction under consideration
|
||||||
by consensus.
|
by consensus.
|
||||||
|
|
||||||
```
|
```{.cpp}
|
||||||
struct Tx
|
struct Tx
|
||||||
{
|
{
|
||||||
using ID = ...;
|
using ID = ...;
|
||||||
@@ -407,13 +405,14 @@ struct Tx
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
[heading Transaction Set]
|
### Transaction Set
|
||||||
The transaction set type =TxSet= represents a set of [^Tx]s that are collectively
|
|
||||||
under consideration by consensus. A =TxSet= can be compared against other [^TxSet]s
|
The transaction set type `TxSet` represents a set of `Tx`s that are collectively
|
||||||
|
under consideration by consensus. A `TxSet` can be compared against other `TxSet`s
|
||||||
(typically from peers) and can be modified to add or remove transactions via
|
(typically from peers) and can be modified to add or remove transactions via
|
||||||
the mutable subtype.
|
the mutable subtype.
|
||||||
|
|
||||||
```
|
```{.cpp}
|
||||||
struct TxSet
|
struct TxSet
|
||||||
{
|
{
|
||||||
using Tx = Tx;
|
using Tx = Tx;
|
||||||
@@ -446,14 +445,16 @@ struct TxSet
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
[heading Ledger] The =Ledger= type represents the state shared amongst the
|
### Ledger
|
||||||
|
|
||||||
|
The `Ledger` type represents the state shared amongst the
|
||||||
distributed participants. Notice that the details of how the next ledger is
|
distributed participants. Notice that the details of how the next ledger is
|
||||||
generated from the prior ledger and the consensus accepted transaction set is
|
generated from the prior ledger and the consensus accepted transaction set is
|
||||||
not part of the interface. Within the generic code, this type is primarily used
|
not part of the interface. Within the generic code, this type is primarily used
|
||||||
to know that peers are working on the same tip of the ledger chain and to
|
to know that peers are working on the same tip of the ledger chain and to
|
||||||
provide some basic timing data for consensus.
|
provide some basic timing data for consensus.
|
||||||
|
|
||||||
```
|
```{.cpp}
|
||||||
struct Ledger
|
struct Ledger
|
||||||
{
|
{
|
||||||
using ID = ...;
|
using ID = ...;
|
||||||
@@ -483,10 +484,13 @@ struct Ledger
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
[heading PeerProposal] The =PeerProposal= type represents the signed position taken
|
### PeerProposal
|
||||||
|
|
||||||
|
The `PeerProposal` type represents the signed position taken
|
||||||
by a peer during consensus. The only type requirement is owning an instance of a
|
by a peer during consensus. The only type requirement is owning an instance of a
|
||||||
generic =ConsensusProposal=.
|
generic `ConsensusProposal`.
|
||||||
```
|
|
||||||
|
```{.cpp}
|
||||||
// Represents our proposed position or a peer's proposed position
|
// Represents our proposed position or a peer's proposed position
|
||||||
// and is provided with the generic code
|
// and is provided with the generic code
|
||||||
template <class NodeID_t, class LedgerID_t, class Position_t> class ConsensusProposal;
|
template <class NodeID_t, class LedgerID_t, class Position_t> class ConsensusProposal;
|
||||||
@@ -502,15 +506,16 @@ struct PeerPosition
|
|||||||
// ... implementation specific
|
// ... implementation specific
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
[heading Generic Consensus Interface]
|
|
||||||
|
|
||||||
The generic =Consensus= relies on =Adaptor= template class to implement a set
|
### Generic Consensus Interface
|
||||||
|
|
||||||
|
The generic `Consensus` relies on `Adaptor` template class to implement a set
|
||||||
of helper functions that plug the consensus algorithm into a specific application.
|
of helper functions that plug the consensus algorithm into a specific application.
|
||||||
The =Adaptor= class also defines the types above needed by the algorithm. Below
|
The `Adaptor` class also defines the types above needed by the algorithm. Below
|
||||||
are excerpts of the generic consensus implementation and of helper types that will
|
are excerpts of the generic consensus implementation and of helper types that will
|
||||||
interact with the concrete implementing class.
|
interact with the concrete implementing class.
|
||||||
|
|
||||||
```
|
```{.cpp}
|
||||||
// Represents a transction under dispute this round
|
// Represents a transction under dispute this round
|
||||||
template <class Tx_t, class NodeID_t> class DisputedTx;
|
template <class Tx_t, class NodeID_t> class DisputedTx;
|
||||||
|
|
||||||
@@ -583,11 +588,12 @@ public:
|
|||||||
// ... details
|
// ... details
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
[heading Adapting Generic Consensus]
|
|
||||||
|
### Adapting Generic Consensus
|
||||||
|
|
||||||
The stub below shows the set of callback/helper functions required in the implementing class.
|
The stub below shows the set of callback/helper functions required in the implementing class.
|
||||||
|
|
||||||
```
|
```{.cpp}
|
||||||
struct Adaptor
|
struct Adaptor
|
||||||
{
|
{
|
||||||
using Ledger_t = Ledger;
|
using Ledger_t = Ledger;
|
||||||
@@ -651,30 +657,27 @@ struct Adaptor
|
|||||||
The implementing class hides many details of the peer communication
|
The implementing class hides many details of the peer communication
|
||||||
model from the generic code.
|
model from the generic code.
|
||||||
|
|
||||||
* The =share= member functions are responsible for sharing the given type with a
|
* The `share` member functions are responsible for sharing the given type with a
|
||||||
node's peers, but are agnostic to the mechanism. Ideally, messages are delivered
|
node's peers, but are agnostic to the mechanism. Ideally, messages are delivered
|
||||||
faster than =LEDGER_GRANULARITY=.
|
faster than `LEDGER_GRANULARITY`.
|
||||||
* The generic code does not specify how transactions are submitted by clients,
|
* The generic code does not specify how transactions are submitted by clients,
|
||||||
propagated through the network or stored in the open ledger. Indeed, the open
|
propagated through the network or stored in the open ledger. Indeed, the open
|
||||||
ledger is only conceptual from the perspective of the generic code---the
|
ledger is only conceptual from the perspective of the generic code---the
|
||||||
initial position and transaction set are opaquely generated in a
|
initial position and transaction set are opaquely generated in a
|
||||||
`Consensus::Result` instance returned from the =onClose= callback.
|
`Consensus::Result` instance returned from the `onClose` callback.
|
||||||
* The calls to =acquireLedger= and =acquireTxSet= only have non-trivial return
|
* The calls to `acquireLedger` and `acquireTxSet` only have non-trivial return
|
||||||
if the ledger or transaction set of interest is available. The implementing
|
if the ledger or transaction set of interest is available. The implementing
|
||||||
class is free to block while acquiring, or return the empty option while
|
class is free to block while acquiring, or return the empty option while
|
||||||
servicing the request asynchronously. Due to legacy reasons, the two calls
|
servicing the request asynchronously. Due to legacy reasons, the two calls
|
||||||
are not symmetric. =acquireTxSet= requires the host application to call
|
are not symmetric. `acquireTxSet` requires the host application to call
|
||||||
=gotTxSet= when an asynchronous =acquire= completes. Conversely,
|
`gotTxSet` when an asynchronous `acquire` completes. Conversely,
|
||||||
=acquireLedger= will be called again later by the consensus code if it still
|
`acquireLedger` will be called again later by the consensus code if it still
|
||||||
desires the ledger with the hope that the asynchronous acquisition is
|
desires the ledger with the hope that the asynchronous acquisition is
|
||||||
complete.
|
complete.
|
||||||
|
|
||||||
[endsect] [/Consensus Type Requirements]
|
|
||||||
|
|
||||||
[section Validation]
|
## Validation
|
||||||
|
|
||||||
Coming Soon!
|
Coming Soon!
|
||||||
|
|
||||||
[endsect] [/Validation]
|
|
||||||
|
|
||||||
[endsect] [/Consensus and Validation]
|
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 13 KiB |
BIN
docs/images/flow1.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
docs/images/flow2.png
Normal file
|
After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "boostbook.dtd">
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
-->
|
|
||||||
|
|
||||||
<section id="rippled.index">
|
|
||||||
<title>Index</title>
|
|
||||||
<index/>
|
|
||||||
</section>
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
[/
|
|
||||||
Copyright (c) Copyright (c) 2012-2017 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.
|
|
||||||
]
|
|
||||||
|
|
||||||
[library rippled
|
|
||||||
[quickbook 1.6]
|
|
||||||
[copyright 2012 - 2017 Ripple Labs Inc.]
|
|
||||||
[purpose C++ Library]
|
|
||||||
[license
|
|
||||||
Distributed under the ISC License
|
|
||||||
]
|
|
||||||
[authors [Labs, Ripple]]
|
|
||||||
[category template]
|
|
||||||
[category generic]
|
|
||||||
]
|
|
||||||
|
|
||||||
[template mdash[] '''— ''']
|
|
||||||
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
|
|
||||||
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
|
|
||||||
|
|
||||||
[include consensus.qbk]
|
|
||||||
|
|
||||||
[section:ref Reference]
|
|
||||||
[include temp/reference.qbk]
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[xinclude index.xml]
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
mkdir -p temp
|
|
||||||
doxygen source.dox
|
|
||||||
xsltproc temp/combine.xslt temp/index.xml > temp/all.xml
|
|
||||||
xsltproc reference.xsl temp/all.xml > temp/reference.qbk
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "boostbook.dtd">
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Copyright (c) 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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<informaltable frame="all">
|
|
||||||
<tgroup cols="3">
|
|
||||||
<colspec colname="a"/>
|
|
||||||
<colspec colname="b"/>
|
|
||||||
<colspec colname="c"/>
|
|
||||||
<thead>
|
|
||||||
<row>
|
|
||||||
<entry valign="center" namest="a" nameend="c">
|
|
||||||
<bridgehead renderas="sect2">Core</bridgehead>
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<row>
|
|
||||||
<entry valign="top">
|
|
||||||
<bridgehead renderas="sect3">Classes</bridgehead>
|
|
||||||
<simplelist type="vert" columns="1">
|
|
||||||
</simplelist>
|
|
||||||
<bridgehead renderas="sect3">Constants</bridgehead>
|
|
||||||
<simplelist type="vert" columns="1">
|
|
||||||
</simplelist>
|
|
||||||
</entry>
|
|
||||||
<entry valign="top">
|
|
||||||
<bridgehead renderas="sect3">Functions</bridgehead>
|
|
||||||
<simplelist type="vert" columns="1">
|
|
||||||
</simplelist>
|
|
||||||
<bridgehead renderas="sect3">Type Traits</bridgehead>
|
|
||||||
<simplelist type="vert" columns="1">
|
|
||||||
</simplelist>
|
|
||||||
</entry>
|
|
||||||
<entry valign="top">
|
|
||||||
<bridgehead renderas="sect3">Types</bridgehead>
|
|
||||||
<simplelist type="vert" columns="1">
|
|
||||||
</simplelist>
|
|
||||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
|
||||||
<simplelist type="vert" columns="1">
|
|
||||||
</simplelist>
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
</tbody>
|
|
||||||
</tgroup>
|
|
||||||
</informaltable>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
|
||||||
|
|
||||||
<!-- Variables (Edit for your project) -->
|
|
||||||
<xsl:variable name="doc-ref" select="'rippled.ref.'"/>
|
|
||||||
<xsl:variable name="doc-ns" select="'ripple'"/>
|
|
||||||
<xsl:variable name="debug" select="0"/>
|
|
||||||
<xsl:variable name="private" select="0"/>
|
|
||||||
<!-- End Variables -->
|
|
||||||
|
|
||||||
<xsl:include href="docca/include/docca/doxygen.xsl"/>
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
|
||||||
|
|
||||||
24
docs/sample_chart.doc
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*!
|
||||||
|
\page somestatechart Example state diagram
|
||||||
|
|
||||||
|
\startuml SomeState "my state diagram"
|
||||||
|
scale 600 width
|
||||||
|
|
||||||
|
[*] -> State1
|
||||||
|
State1 --> State2 : Succeeded
|
||||||
|
State1 --> [*] : Aborted
|
||||||
|
State2 --> State3 : Succeeded
|
||||||
|
State2 --> [*] : Aborted
|
||||||
|
state State3 {
|
||||||
|
state "Accumulate Enough Data\nLong State Name" as long1
|
||||||
|
long1 : Just a test
|
||||||
|
[*] --> long1
|
||||||
|
long1 --> long1 : New Data
|
||||||
|
long1 --> ProcessData : Enough Data
|
||||||
|
}
|
||||||
|
State3 --> State3 : Failed
|
||||||
|
State3 --> [*] : Succeeded / Save Result
|
||||||
|
State3 --> [*] : Aborted
|
||||||
|
|
||||||
|
\enduml
|
||||||
|
*/
|
||||||
@@ -6,6 +6,7 @@ PROJECT_NAME = "rippled"
|
|||||||
PROJECT_NUMBER =
|
PROJECT_NUMBER =
|
||||||
PROJECT_BRIEF = C++ Library
|
PROJECT_BRIEF = C++ Library
|
||||||
PROJECT_LOGO =
|
PROJECT_LOGO =
|
||||||
|
PROJECT_LOGO = images/LogoForDocumentation.png
|
||||||
OUTPUT_DIRECTORY =
|
OUTPUT_DIRECTORY =
|
||||||
CREATE_SUBDIRS = NO
|
CREATE_SUBDIRS = NO
|
||||||
ALLOW_UNICODE_NAMES = NO
|
ALLOW_UNICODE_NAMES = NO
|
||||||
@@ -125,6 +126,41 @@ INPUT = \
|
|||||||
../src/ripple/app/tx/applySteps.h \
|
../src/ripple/app/tx/applySteps.h \
|
||||||
../src/ripple/app/tx/impl/InvariantCheck.h \
|
../src/ripple/app/tx/impl/InvariantCheck.h \
|
||||||
../src/ripple/app/consensus/RCLValidations.h \
|
../src/ripple/app/consensus/RCLValidations.h \
|
||||||
|
../src/README.md \
|
||||||
|
../src/ripple/README.md \
|
||||||
|
../README.md \
|
||||||
|
../RELEASENOTES.md \
|
||||||
|
../docs/CodingStyle.md \
|
||||||
|
../docs/CheatSheet.md \
|
||||||
|
../docs/README.md \
|
||||||
|
../docs/sample_chart.doc \
|
||||||
|
../docs/HeapProfiling.md \
|
||||||
|
../docs/Docker.md \
|
||||||
|
../docs/consensus.md \
|
||||||
|
../Builds/XCode/README.md \
|
||||||
|
../Builds/VisualStudio2015/README.md \
|
||||||
|
../src/ripple/consensus/README.md \
|
||||||
|
../src/ripple/app/consensus/README.md \
|
||||||
|
../src/test/csf/README.md \
|
||||||
|
../src/ripple/basics/README.md \
|
||||||
|
../src/ripple/crypto/README.md \
|
||||||
|
../src/ripple/peerfinder/README.md \
|
||||||
|
../src/ripple/app/misc/README.md \
|
||||||
|
../src/ripple/app/misc/FeeEscalation.md \
|
||||||
|
../src/ripple/app/ledger/README.md \
|
||||||
|
../src/ripple/app/paths/README.md \
|
||||||
|
../src/ripple/app/tx/README.md \
|
||||||
|
../src/ripple/proto/README.md \
|
||||||
|
../src/ripple/shamap/README.md \
|
||||||
|
../src/ripple/protocol/README.md \
|
||||||
|
../src/ripple/json/README.md \
|
||||||
|
../src/ripple/json/TODO.md \
|
||||||
|
../src/ripple/resource/README.md \
|
||||||
|
../src/ripple/rpc/README.md \
|
||||||
|
../src/ripple/overlay/README.md \
|
||||||
|
../src/ripple/nodestore/README.md \
|
||||||
|
../src/ripple/nodestore/Benchmarks.md \
|
||||||
|
|
||||||
|
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
FILE_PATTERNS =
|
FILE_PATTERNS =
|
||||||
@@ -136,12 +172,16 @@ EXCLUDE_SYMBOLS =
|
|||||||
EXAMPLE_PATH =
|
EXAMPLE_PATH =
|
||||||
EXAMPLE_PATTERNS =
|
EXAMPLE_PATTERNS =
|
||||||
EXAMPLE_RECURSIVE = NO
|
EXAMPLE_RECURSIVE = NO
|
||||||
IMAGE_PATH =
|
IMAGE_PATH = \
|
||||||
|
./images/ \
|
||||||
|
./images/consensus/ \
|
||||||
|
../src/test/csf/ \
|
||||||
|
|
||||||
INPUT_FILTER =
|
INPUT_FILTER =
|
||||||
FILTER_PATTERNS =
|
FILTER_PATTERNS =
|
||||||
FILTER_SOURCE_FILES = NO
|
FILTER_SOURCE_FILES = NO
|
||||||
FILTER_SOURCE_PATTERNS =
|
FILTER_SOURCE_PATTERNS =
|
||||||
USE_MDFILE_AS_MAINPAGE =
|
USE_MDFILE_AS_MAINPAGE = ../src/README.md
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to source browsing
|
# Configuration options related to source browsing
|
||||||
@@ -168,8 +208,8 @@ IGNORE_PREFIX =
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the HTML output
|
# Configuration options related to the HTML output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
GENERATE_HTML = NO
|
GENERATE_HTML = YES
|
||||||
HTML_OUTPUT = dhtm
|
HTML_OUTPUT = html_doc
|
||||||
HTML_FILE_EXTENSION = .html
|
HTML_FILE_EXTENSION = .html
|
||||||
HTML_HEADER =
|
HTML_HEADER =
|
||||||
HTML_FOOTER =
|
HTML_FOOTER =
|
||||||
@@ -269,8 +309,8 @@ MAN_LINKS = NO
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the XML output
|
# Configuration options related to the XML output
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
GENERATE_XML = YES
|
GENERATE_XML = NO
|
||||||
XML_OUTPUT = temp/
|
XML_OUTPUT = temp
|
||||||
XML_PROGRAMLISTING = YES
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@@ -346,7 +386,7 @@ DOT_PATH =
|
|||||||
DOTFILE_DIRS =
|
DOTFILE_DIRS =
|
||||||
MSCFILE_DIRS =
|
MSCFILE_DIRS =
|
||||||
DIAFILE_DIRS =
|
DIAFILE_DIRS =
|
||||||
PLANTUML_JAR_PATH =
|
PLANTUML_JAR_PATH = $(PLANTUML_JAR)
|
||||||
PLANTUML_INCLUDE_PATH =
|
PLANTUML_INCLUDE_PATH =
|
||||||
DOT_GRAPH_MAX_NODES = 50
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
MAX_DOT_GRAPH_DEPTH = 0
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
|||||||
BIN
images/flow1.png
|
Before Width: | Height: | Size: 102 KiB |
BIN
images/flow2.png
|
Before Width: | Height: | Size: 90 KiB |
@@ -1,4 +1,4 @@
|
|||||||
### Newest Style
|
# Ripple Source Guidelines
|
||||||
|
|
||||||
Each folder contains a single module following the newest style:
|
Each folder contains a single module following the newest style:
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
# Overlay
|
|
||||||