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
|
||||
HtmlDocumentation
|
||||
docs/html_doc
|
||||
|
||||
# Xcode user-specific project settings
|
||||
# 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"]
|
||||
path = src/nudb/extras/beast
|
||||
url = https://github.com/vinniefalco/Beast.git
|
||||
|
||||
@@ -32,7 +32,6 @@ addons:
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Default BUILD is "scons".
|
||||
|
||||
- compiler: gcc
|
||||
env: GCC_VER=5 BUILD=cmake TARGET=debug
|
||||
|
||||
@@ -32,7 +32,7 @@ package() {
|
||||
cd "$srcdir/$pkgname"
|
||||
install -D -m644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||
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/log/$pkgname"
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ RUN cd src/; scons build/rippled
|
||||
RUN cp src/build/rippled rippled; strip rippled
|
||||
|
||||
# copy default config
|
||||
RUN cp src/doc/rippled-example.cfg rippled.cfg
|
||||
RUN cp src/cfg/rippled-example.cfg rippled.cfg
|
||||
|
||||
# clean source
|
||||
RUN rm -r src
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set -e
|
||||
|
||||
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
|
||||
mv build/docker/rippled-example.cfg build/docker/rippled.cfg
|
||||
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
|
||||
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".
|
||||
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.
|
||||
prepend(doc_srcs
|
||||
docs/
|
||||
Jamfile.v2
|
||||
boostbook.dtd
|
||||
consensus.qbk
|
||||
index.xml
|
||||
main.qbk
|
||||
quickref.xml
|
||||
reference.xsl
|
||||
source.dox)
|
||||
|
||||
file(GLOB_RECURSE other_docs docs/*.md)
|
||||
list(APPEND doc_srcs "${other_docs}")
|
||||
set_property(
|
||||
SOURCE ${doc_srcs}
|
||||
APPEND
|
||||
@@ -484,52 +479,32 @@ list(APPEND targets ${other_target})
|
||||
# other_target when the user builds the solution (default when pressing <F7>)
|
||||
set_property(TARGET ${other_target} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD true)
|
||||
|
||||
find_program(
|
||||
B2_EXE
|
||||
NAMES b2
|
||||
HINTS ${BOOST_ROOT}
|
||||
PATHS ${BOOST_ROOT}
|
||||
DOC "Location of the b2 build executable from Boost")
|
||||
if(${B2_EXE} STREQUAL "B2_EXE-NOTFOUND")
|
||||
find_package(Doxygen)
|
||||
if(TARGET Doxygen::doxygen)
|
||||
if (NOT DEFINED ENV{PLANTUML_JAR})
|
||||
message(WARNING
|
||||
"Boost b2 executable not found. docs target will not be buildable")
|
||||
elseif(NOT BOOST_ROOT)
|
||||
if(Boost_INCLUDE_DIRS)
|
||||
set(BOOST_ROOT ${Boost_INCLUDE_DIRS})
|
||||
else()
|
||||
get_filename_component(BOOST_ROOT ${B2_EXE} DIRECTORY)
|
||||
"PLANTUML_JAR not set - @startuml diagrams will not generate")
|
||||
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"
|
||||
# read the source config and make a modified one
|
||||
# that points the output files to our build directory
|
||||
FILE(READ "${CMAKE_SOURCE_DIR}/docs/source.dox" dox_content)
|
||||
string(REGEX REPLACE "[\t ]*OUTPUT_DIRECTORY[\t ]*=(.*)"
|
||||
"OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}\n\\1"
|
||||
new_config "${dox_content}")
|
||||
FILE(WRITE "${CMAKE_BINARY_DIR}/source.dox" "${new_config}")
|
||||
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()
|
||||
|
||||
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 ;
|
||||
|
||||
367
Jenkinsfile
vendored
@@ -74,11 +74,11 @@ try {
|
||||
|
||||
if (! collab_found) {
|
||||
manager.addShortText(
|
||||
"Author of this change is not a collaborator!",
|
||||
"Crimson",
|
||||
"white",
|
||||
"0px",
|
||||
"white")
|
||||
'Author of this change is not a collaborator!',
|
||||
'Crimson',
|
||||
'white',
|
||||
'0px',
|
||||
'white')
|
||||
all_status['startup'] =
|
||||
[false, 'Author Check', "$CHANGE_AUTHOR is not a collaborator!"]
|
||||
error "$CHANGE_AUTHOR does not appear to be a collaborator...bailing on this build"
|
||||
@@ -88,93 +88,262 @@ try {
|
||||
}
|
||||
|
||||
stage ('Parallel Build') {
|
||||
def variants = [
|
||||
'coverage',
|
||||
'clang.debug.unity',
|
||||
'clang.debug.nounity',
|
||||
'gcc.debug.unity',
|
||||
'gcc.debug.nounity',
|
||||
'clang.release.unity',
|
||||
'gcc.release.unity'] as String[]
|
||||
String[][] variants = [
|
||||
['coverage'],
|
||||
['docs'],
|
||||
['msvc.debug'],
|
||||
// This one does not currently build (TBD):
|
||||
//['msvc.debug.nounity'],
|
||||
['msvc.debug', '', 'PROJECT_NAME=rippled_classic'],
|
||||
['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
|
||||
// that we want to run. The map
|
||||
// is string keys and node{} object values
|
||||
def builds = [:]
|
||||
for (int index = 0; index < variants.size(); index++) {
|
||||
def bldtype = variants[index]
|
||||
builds[bldtype] = {
|
||||
node('rippled-dev') {
|
||||
def bldtype = variants[index][0]
|
||||
def cmake_extra = variants[index].size() > 1 ? variants[index][1] : ''
|
||||
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
|
||||
dir ('build') {
|
||||
deleteDir()
|
||||
}
|
||||
def cdir = upDir(pwd())
|
||||
echo "BASEDIR: ${cdir}"
|
||||
def compiler = getCompiler(bldtype)
|
||||
def target = getTarget(bldtype)
|
||||
if (compiler == "coverage") {
|
||||
compiler = 'gcc'
|
||||
}
|
||||
echo "COMPILER: ${compiler}"
|
||||
echo "TARGET: ${target}"
|
||||
def clang_cc =
|
||||
(compiler == "clang") ? "${LLVM_ROOT}/bin/clang" : ''
|
||||
def clang_cxx =
|
||||
(compiler == "clang") ? "${LLVM_ROOT}/bin/clang++" : ''
|
||||
def ucc = isNoUnity(target) ? 'true' : 'false'
|
||||
echo "CONFIG: ${config}"
|
||||
echo "USE_CC: ${ucc}"
|
||||
withEnv(["CCACHE_BASEDIR=${cdir}",
|
||||
"CCACHE_NOHASHDIR=true",
|
||||
if (compiler == 'msvc') {
|
||||
env_vars.addAll([
|
||||
'BOOST_ROOT=c:\\lib\\boost_1_66',
|
||||
'PROJECT_NAME=rippled',
|
||||
'MSBUILDDISABLENODEREUSE=1', // this ENV setting is probably redundant since we also pass /nr:false to msbuild
|
||||
'OPENSSL_ROOT=c:\\OpenSSL-Win64'])
|
||||
}
|
||||
else {
|
||||
env_vars.addAll([
|
||||
'NINJA_BUILD=false',
|
||||
"CCACHE_BASEDIR=${cdir}",
|
||||
'PLANTUML_JAR=/opt/plantuml/plantuml.jar',
|
||||
'CCACHE_NOHASHDIR=true',
|
||||
"CC=${cc}",
|
||||
"CXX=${cxx}",
|
||||
'LCOV_ROOT=""',
|
||||
"TARGET=${target}",
|
||||
"CC=${compiler}",
|
||||
'BUILD=cmake',
|
||||
'VERBOSE_BUILD=true',
|
||||
"CLANG_CC=${clang_cc}",
|
||||
"CLANG_CXX=${clang_cxx}",
|
||||
'PATH+CMAKE_BIN=/opt/local/cmake',
|
||||
'GDB_ROOT=/opt/local/gdb',
|
||||
'BOOST_ROOT=/opt/local/boost_1_66_0',
|
||||
"USE_CCACHE=${ucc}"])
|
||||
}
|
||||
|
||||
if (extra_env.size() > 0) {
|
||||
env_vars.addAll(extra_env)
|
||||
}
|
||||
|
||||
withCredentials(
|
||||
[string(
|
||||
credentialsId: 'RIPPLED_CODECOV_TOKEN',
|
||||
variable: 'CODECOV_TOKEN')])
|
||||
{
|
||||
myStage(bldtype)
|
||||
withEnv(env_vars) {
|
||||
myStage(bldlabel)
|
||||
try {
|
||||
sh "ccache -s > ${bldtype}.txt"
|
||||
// the devtoolset from SCL gives us a recent gcc. It's
|
||||
// not strictly needed when we are building with clang,
|
||||
// but it doesn't seem to interfere either
|
||||
sh "source /opt/rh/devtoolset-6/enable && " +
|
||||
"(/usr/bin/time -p ./bin/ci/ubuntu/build-and-test.sh 2>&1) 2>&1 " +
|
||||
">> ${bldtype}.txt"
|
||||
sh "ccache -s >> ${bldtype}.txt"
|
||||
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 = readFile("${bldtype}.txt")
|
||||
def st = getResults(outstr)
|
||||
def time = getTime(outstr)
|
||||
def fail_count = getFailures(outstr)
|
||||
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 = bldtype
|
||||
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("${bldtype}.txt")
|
||||
'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[bldtype] =
|
||||
[fail_count == 0, bldtype, "${st}, t: ${time}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -183,7 +352,7 @@ finally {
|
||||
stage ('Final Status') {
|
||||
node {
|
||||
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 results = """
|
||||
@@ -195,19 +364,19 @@ Built at __${datestamp}__
|
||||
|
||||
### Test Results
|
||||
|
||||
Build Type | Result | Status
|
||||
---------- | ------ | ------
|
||||
Build Type | Log | Result | Status
|
||||
---------- | --- | ------ | ------
|
||||
"""
|
||||
for ( e in all_status) {
|
||||
results += e.value[1] + " | " + e.value[2] + " | " +
|
||||
(e.value[0] ? "PASS :white_check_mark: " : "FAIL :red_circle: ") + "\n"
|
||||
results += e.value[1] + ' | ' + e.value[3] + ' | ' + e.value[2] + ' | ' +
|
||||
(e.value[0] ? 'PASS :white_check_mark: ' : 'FAIL :red_circle: ') + '\n'
|
||||
}
|
||||
results += "\n"
|
||||
echo "FINAL BUILD RESULTS"
|
||||
results += '\n'
|
||||
echo 'FINAL BUILD RESULTS'
|
||||
echo results
|
||||
|
||||
try {
|
||||
def url_comment = ""
|
||||
def url_comment = ''
|
||||
if (env.CHANGE_ID && env.CHANGE_ID ==~ /\d+/) {
|
||||
//
|
||||
// CHANGE_ID indicates we are building a PR
|
||||
@@ -251,7 +420,7 @@ Build Type | Result | Status
|
||||
}
|
||||
|
||||
if (comment_id == 0) {
|
||||
echo "no existing status comment found"
|
||||
echo 'no existing status comment found'
|
||||
}
|
||||
|
||||
def body = JsonOutput.toJson([
|
||||
@@ -266,8 +435,8 @@ Build Type | Result | Status
|
||||
httpMode: mode,
|
||||
requestBody: body)
|
||||
}
|
||||
catch (any) {
|
||||
echo "had a problem interacting with github...status is probably not updated"
|
||||
catch (e) {
|
||||
echo 'had a problem interacting with github...status is probably not updated'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,24 +464,54 @@ ${log}
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
def getResults(text) {
|
||||
def getResults(text, label) {
|
||||
// example:
|
||||
/// 194.5s, 154 suites, 948 cases, 360485 tests total, 0 failures
|
||||
def matcher = text =~ /(\d+) cases, (\d+) tests total, (\d+) (failure(s?))/
|
||||
matcher ? matcher[0][1] + " cases, " + matcher[0][3] + " failed" : "no test results"
|
||||
// or build log format:
|
||||
// [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) {
|
||||
// example:
|
||||
/// 194.5s, 154 suites, 948 cases, 360485 tests total, 0 failures
|
||||
def matcher = text =~ /(\d+) tests total, (\d+) (failure(s?))/
|
||||
def getFailures(text, label) {
|
||||
// [see above for format]
|
||||
def matcher =
|
||||
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
|
||||
// probably wrong, e.g. maybe the build failed...
|
||||
matcher ? matcher[0][2] as Integer : 1i
|
||||
}
|
||||
|
||||
@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 =~ /^(.+?)\.(.+)$/
|
||||
matcher ? matcher[0][1] : bld
|
||||
}
|
||||
@@ -324,7 +523,7 @@ def isNoUnity(bld) {
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
def getTarget(bld) {
|
||||
def getSecondPart(bld) {
|
||||
def matcher = bld =~ /^(.+?)\.(.+)$/
|
||||
matcher ? matcher[0][2] : bld
|
||||
}
|
||||
@@ -337,12 +536,4 @@ def upDir(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?
|
||||
|
||||

|
||||
|
||||
> **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
|
||||
transactions on a secure distributed database, the Ripple Consensus Ledger
|
||||
(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
|
||||
challenging.
|
||||
|
||||

|
||||

|
||||
|
||||
### XRP as a Bridge Currency
|
||||
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
|
||||
costs, and ultimately, offer more competitive FX pricing.
|
||||
|
||||

|
||||

|
||||
|
||||
# rippled - Ripple server
|
||||
`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. |
|
||||
| ./build | Intermediate and final build outputs. |
|
||||
| ./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. |
|
||||
|
||||
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/
|
||||
|
||||
**Do you work at a digital asset exchange or wallet provider?**
|
||||
|
||||
Please [contact us](mailto:support@ripple.com). We can help guide your integration.
|
||||
> **Do you work at a digital asset exchange or wallet provider?**
|
||||
>
|
||||
> Please [contact us](mailto:support@ripple.com). We can help guide your integration.
|
||||
|
||||
## 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).
|
||||
|
||||
# Releases
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
set -ex
|
||||
__dirname=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
echo "using CC: $CC"
|
||||
"${CC}" --version
|
||||
COMPNAME=$(basename $CC)
|
||||
echo "using CXX: ${CXX:-notset}"
|
||||
if [[ $CXX ]]; then
|
||||
"${CXX}" --version
|
||||
fi
|
||||
echo "using TARGET: $TARGET"
|
||||
|
||||
# Ensure APP defaults to rippled if it's not set.
|
||||
@@ -25,42 +31,69 @@ else
|
||||
time=
|
||||
fi
|
||||
|
||||
if [[ ${BUILD:-scons} == "cmake" ]]; then
|
||||
if [[ ${BUILD:-cmake} == "cmake" ]]; then
|
||||
echo "cmake building ${APP}"
|
||||
CMAKE_EXTRA_ARGS=" -DCMAKE_VERBOSE_MAKEFILE=ON"
|
||||
CMAKE_TARGET=$CC.$TARGET
|
||||
BUILDARGS=" -j${JOBS}"
|
||||
if [[ ${VERBOSE_BUILD:-} == true ]]; then
|
||||
# TODO: if we use a different generator, this
|
||||
# option to build verbose would need to change:
|
||||
BUILDARGS+=" verbose=1"
|
||||
: ${CMAKE_EXTRA_ARGS:=""}
|
||||
if [[ ${NINJA_BUILD:-} == true ]]; then
|
||||
CMAKE_EXTRA_ARGS+=" -G Ninja"
|
||||
fi
|
||||
CMAKE_TARGET=${COMPNAME}.${TARGET}
|
||||
if [[ ${CI:-} == true ]]; then
|
||||
CMAKE_TARGET=$CMAKE_TARGET.ci
|
||||
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
|
||||
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
|
||||
if [ -d "build/${CMAKE_TARGET}" ]; then
|
||||
rm -rf "build/${CMAKE_TARGET}"
|
||||
if [ -d "build/${BUILD_DIR}" ]; then
|
||||
rm -rf "build/${BUILD_DIR}"
|
||||
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}
|
||||
if [[ ${TARGET} == "docs" ]]; then
|
||||
$time cmake --build . --target docs -- $BUILDARGS
|
||||
## mimic the standard test output for docs build
|
||||
## to make controlling processes like jenkins happy
|
||||
if [ -f html_doc/index.html ]; then
|
||||
echo "1 case, 1 test total, 0 failures"
|
||||
else
|
||||
echo "1 case, 1 test total, 1 failures"
|
||||
fi
|
||||
exit
|
||||
else
|
||||
$time cmake --build . -- $BUILDARGS
|
||||
if [[ ${BUILD_BOTH:-} == true ]]; then
|
||||
if [[ ${TARGET} == *.unity ]]; then
|
||||
$time cmake --build . --target rippled_classic -- $BUILDARGS
|
||||
cmake --build . --target rippled_classic -- $BUILDARGS
|
||||
else
|
||||
$time cmake --build . --target rippled_unity -- $BUILDARGS
|
||||
cmake --build . --target rippled_unity -- $BUILDARGS
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
popd
|
||||
export APP_PATH="$PWD/build/${CMAKE_TARGET}/${APP}"
|
||||
export APP_PATH="$PWD/build/${BUILD_DIR}/${APP}"
|
||||
echo "using APP_PATH: $APP_PATH"
|
||||
else
|
||||
export APP_PATH="$PWD/build/$CC.$TARGET/${APP}"
|
||||
export APP_PATH="$PWD/build/${COMPNAME}.${TARGET}/${APP}"
|
||||
echo "using APP_PATH: $APP_PATH"
|
||||
# Make sure vcxproj is up to date
|
||||
$time scons vcxproj
|
||||
@@ -68,21 +101,21 @@ else
|
||||
# $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
|
||||
# indicates that 2 cores are available to containers.
|
||||
$time scons -j${JOBS} $CC.$TARGET
|
||||
$time scons -j${JOBS} ${COMPNAME}.$TARGET
|
||||
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
|
||||
ldd $APP_PATH
|
||||
|
||||
if [[ ${APP} == "rippled" ]]; then
|
||||
export APP_ARGS+=" --unittest --quiet --unittest-log"
|
||||
APP_ARGS+="--unittest --quiet --unittest-log"
|
||||
# Only report on src/ripple files
|
||||
export LCOV_FILES="*/src/ripple/*"
|
||||
# Nothing to explicitly exclude
|
||||
export LCOV_EXCLUDE_FILES="LCOV_NO_EXCLUDE"
|
||||
if [[ $TARGET != "coverage" && ${PARALLEL_TESTS:-} == true ]]; then
|
||||
APP_ARGS+=" --unittest-jobs ${JOBS}"
|
||||
fi
|
||||
else
|
||||
: ${APP_ARGS:=}
|
||||
: ${LCOV_FILES:="*/src/*"}
|
||||
@@ -106,6 +139,7 @@ if [[ $TARGET == debug* && -v GDB_ROOT && -x $GDB_ROOT/bin/gdb ]]; then
|
||||
$GDB_ROOT/bin/gdb -v
|
||||
# Execute unit tests under gdb, printing a call stack
|
||||
# if we get a crash.
|
||||
export APP_ARGS
|
||||
$GDB_ROOT/bin/gdb -return-child-result -quiet -batch \
|
||||
-ex "set env MALLOC_CHECK_=3" \
|
||||
-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.
|
||||
- Place each data member on its own line.
|
||||
@@ -11,7 +13,7 @@
|
||||
- Order class declarations as types, public, protected, private, then data.
|
||||
- Prefer 'private' over 'protected'
|
||||
|
||||
# Function
|
||||
## Function
|
||||
|
||||
- Minimize external dependencies
|
||||
* Pass options in the ctor instead of using theConfig
|
||||
@@ -1,5 +1,3 @@
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Coding Standards
|
||||
|
||||
Coding standards used here gradually evolve and propagate through
|
||||
@@ -1,22 +1,31 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get -y install build-essential g++ git libbz2-dev wget python-dev
|
||||
RUN apt -y update
|
||||
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
|
||||
ENV BOOST_SHA 440a59f8bc4023dbe6285c9998b0f7fa288468b889746b1ef00e8b36c559dce1
|
||||
RUN wget https://sourceforge.net/projects/boost/files/boost/1.62.0/boost_1_62_0.tar.gz
|
||||
RUN echo "$BOOST_SHA boost_1_62_0.tar.gz" | sha256sum -c
|
||||
RUN tar xzf boost_1_62_0.tar.gz
|
||||
RUN cd boost_1_62_0 && ./bootstrap.sh --prefix=/usr/local
|
||||
RUN cd boost_1_62_0 && ./b2 install
|
||||
ENV BOOST_ROOT=/boost_1_62_0
|
||||
RUN cd /tmp
|
||||
ENV CM_INSTALLER=cmake-3.10.0-rc3-Linux-x86_64.sh
|
||||
ENV CM_VER_DIR=/opt/local/cmake-3.10.0
|
||||
RUN cd /tmp && wget https://cmake.org/files/v3.10/$CM_INSTALLER && chmod a+x $CM_INSTALLER
|
||||
RUN mkdir -p $CM_VER_DIR
|
||||
RUN ln -s $CM_VER_DIR /opt/local/cmake
|
||||
RUN /tmp/$CM_INSTALLER --prefix=$CM_VER_DIR --exclude-subdir
|
||||
RUN rm -f /tmp/$CM_INSTALLER
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get -y install doxygen
|
||||
RUN apt-get -y install xsltproc
|
||||
RUN cd /tmp && wget https://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.14.src.tar.gz
|
||||
RUN cd /tmp && tar xvf doxygen-1.8.14.src.tar.gz
|
||||
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 && \
|
||||
chmod +x makeqbk.sh && \
|
||||
./makeqbk.sh && \
|
||||
$BOOST_ROOT/b2
|
||||
RUN mkdir -p /opt/plantuml
|
||||
RUN wget -O /opt/plantuml/plantuml.jar http://sourceforge.net/projects/plantuml/files/plantuml.jar/download
|
||||
ENV PLANTUML_JAR=/opt/plantuml/plantuml.jar
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
@@ -38,47 +23,54 @@ Install these dependencies:
|
||||
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
|
||||
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
|
||||
|
||||
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/
|
||||
```
|
||||
1. Install doxygen using your package manager OR from source using the links above.
|
||||
|
||||
## Setup project submodules
|
||||
### [Optional] Install Plantuml (all platforms)
|
||||
|
||||
1. Open a shell in your rippled root folder.
|
||||
2. `git submodule init`
|
||||
3. `git submodule update docs/docca`
|
||||
Doxygen supports the optional use of [plantuml](http://plantuml.com) to
|
||||
generate diagrams from `@startuml` sections. We don't currently rely on this
|
||||
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
|
||||
|
||||
### Windows & MacOS
|
||||
### all platforms
|
||||
|
||||
From the rippled root folder:
|
||||
```
|
||||
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
|
||||
```
|
||||
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
|
||||
presence of faulty or even malicious participants. This document outlines the
|
||||
[@https://ripple.com/files/ripple/consensus/whitepaper.pdf Ripple Consensus
|
||||
Algorithm] as implemented in [@https://github.com/ripple/rippled rippled], but
|
||||
[Ripple Consensus Algorithm](https://ripple.com/files/ripple/consensus/whitepaper.pdf)
|
||||
as implemented in [rippled](https://github.com/ripple/rippled), but
|
||||
focuses on its utility as a generic consensus algorithm independent of the
|
||||
detailed mechanics of the Ripple Consensus Ledger. Most notably, the algorithm
|
||||
does not require fully synchronous communication between all nodes in the
|
||||
network, or even a fixed network topology, but instead achieves consensus via
|
||||
collectively trusted subnetworks.
|
||||
|
||||
[heading Distributed Agreement]
|
||||
## Distributed Agreement
|
||||
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
collectively trusted to not collude in an attempt to defraud the participant.
|
||||
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.
|
||||
* /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.
|
||||
|
||||
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
|
||||
and was abandoned.
|
||||
|
||||
[$images/consensus/block_chain.png]
|
||||

|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
distinguish it from all other ledgers. During consensus, the /previous/,
|
||||
/prior/ or /last-closed/ ledger is the most recent ledger seen by consensus
|
||||
* The *ledger* is the shared distributed state. Each ledger has a unique ID to
|
||||
distinguish it from all other ledgers. During consensus, the *previous*,
|
||||
*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.
|
||||
* 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.
|
||||
* 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
|
||||
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
|
||||
generate a new ledger. A unique ID distinguishes a set of transactions from
|
||||
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.
|
||||
* 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
|
||||
symmetric, since participants can decide on their chosen sets independently.
|
||||
* 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
disputed transactions from its position based on that transaction's support
|
||||
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.
|
||||
Instead, a node can request the transaction set from the network if necessary.
|
||||
|
||||
[heading Overview ]
|
||||
[$images/consensus/consensus_overview.png [width 50%] [height 50%] ]
|
||||
### Overview
|
||||
|
||||

|
||||
|
||||
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
|
||||
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
|
||||
[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:
|
||||
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
which transactions should be accepted in the closed ledger.
|
||||
* 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
|
||||
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.
|
||||
|
||||
Throughout, a heartbeat timer calls =timerEntry= at a regular frequency to drive
|
||||
the process forward. Although the =startRound= call occurs at arbitrary times
|
||||
Throughout, a heartbeat timer calls `timerEntry` at a regular frequency to drive
|
||||
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
|
||||
transactions, the transitions from =Open= to =Establish= and =Establish= to
|
||||
=Accept= only occur during calls to =timerEntry=. Similarly, transactions can
|
||||
transactions, the transitions from `Open` to `Establish` and `Establish` to
|
||||
`Accept` only occur during calls to `timerEntry`. Similarly, transactions can
|
||||
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
|
||||
by the light green triangles.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
meaningful and are represented above by the circle with the X in it. Only
|
||||
proposals from chosen peers are considered.
|
||||
|
||||
[#effective_close_time]
|
||||
[heading Effective Close Time]
|
||||
### Effective Close Time ### {#effective_close_time}
|
||||
|
||||
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
|
||||
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
|
||||
/effective close time/ that nodes seek to agree on. This allows servers to
|
||||
multiple of the current *effective close time resolution*. It is this
|
||||
*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
|
||||
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
|
||||
resolution. The purple arrow represents a peer whose estimate rounds to a
|
||||
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
|
||||
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
|
||||
reach close time consensus.
|
||||
|
||||
[heading Modes]
|
||||
### Modes
|
||||
|
||||
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.
|
||||
|
||||
* /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.
|
||||
* /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
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
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,
|
||||
it defers to peer positions for determining the consensus outcome as if it
|
||||
were just /observing/.
|
||||
* /Switch Ledger/ indicates that the node has acquired the correct prior ledger
|
||||
were just *observing*.
|
||||
* *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
|
||||
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.
|
||||
|
||||
[$images/consensus/consensus_modes.png]
|
||||

|
||||
|
||||
Once either wrong ledger or switch ledger are reached, the node cannot
|
||||
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
|
||||
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
|
||||
through 3 phases. There are 4 public methods of the generic consensus algorithm
|
||||
that determine this progression
|
||||
|
||||
* =startRound= begins a consensus round.
|
||||
* =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=
|
||||
or =Accept=.
|
||||
* =peerProposal= is called whenever a peer proposal is received and is what
|
||||
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
|
||||
* `startRound` begins a consensus round.
|
||||
* `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`
|
||||
or `Accept`.
|
||||
* `peerProposal` is called whenever a peer proposal is received and is what
|
||||
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
|
||||
is typically in response to a prior request from the node to acquire the
|
||||
transaction set corresponding to a disagreeing peer's position.
|
||||
|
||||
The following subsections describe each consensus phase in more detail and what
|
||||
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.
|
||||
A shorter window reduces the latency to generating the next ledger, but also
|
||||
reduces transaction throughput due to fewer transactions accepted into the
|
||||
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.
|
||||
Calls to =peerProposal= or =gotTxSet= simply store the proposal or transaction
|
||||
set for use in the coming =Establish= phase.
|
||||
Calls to `peerProposal` or `gotTxSet` simply store the proposal or transaction
|
||||
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.
|
||||
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.
|
||||
|
||||
['Ledger Close]
|
||||
##### Ledger Close
|
||||
|
||||
Under normal circumstances, the open ledger period ends when one of the following
|
||||
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.
|
||||
* if there are no open transactions and a suitably longer idle interval has
|
||||
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
|
||||
for transactions 2,3 and 4, since at least one peer position differs on each.
|
||||
|
||||
[#disputes_image]
|
||||
[$images/consensus/disputes.png [width 20%] [height 20%]]
|
||||
##### disputes ##### {#disputes_image}
|
||||
|
||||

|
||||
|
||||
[h6 Establish]
|
||||
#### Establish
|
||||
|
||||
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
|
||||
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.
|
||||
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
|
||||
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
|
||||
ledger. Otherwise, the node updates the node's position and considers whether
|
||||
to switch to the =Accepted= phase and declare consensus reached. However, at
|
||||
least =LEDGER_MIN_CONSENSUS= time must have elapsed before doing either. This
|
||||
to switch to the `Accepted` phase and declare consensus reached. However, at
|
||||
least `LEDGER_MIN_CONSENSUS` time must have elapsed before doing either. This
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
support. The constants that define the thresholds and durations at which the
|
||||
thresholds change are given by `AV_XXX_CONSENSUS_PCT` and
|
||||
`AV_XXX_CONSENSUS_TIME` respectively, where =XXX= is =INIT=,=MID=,=LATE= and
|
||||
=STUCK=. The effective close time position is updated using the same
|
||||
`AV_XXX_CONSENSUS_TIME` respectively, where `XXX` is `INIT`,`MID`,`LATE` and
|
||||
`STUCK`. The effective close time position is updated using the same
|
||||
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
|
||||
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
|
||||
@@ -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,
|
||||
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
|
||||
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
|
||||
* 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
|
||||
* =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
|
||||
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
|
||||
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
|
||||
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
|
||||
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,
|
||||
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.
|
||||
|
||||
#### 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
|
||||
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=
|
||||
to kick off the next consensus round. The =startRound= call includes the new
|
||||
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
|
||||
prior ledger, prior ledger ID and whether the round should begin in the
|
||||
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
|
||||
network if necessary.
|
||||
|
||||
[endsect] [/Consensus Overview]
|
||||
|
||||
[section Consensus Type Requirements]
|
||||
## Consensus Type Requirements
|
||||
|
||||
The consensus type requirements are given below as minimal implementation stubs.
|
||||
Actual implementations would augment these stubs with members appropriate for
|
||||
managing the details of transactions and ledgers within the larger application
|
||||
framework.
|
||||
|
||||
[heading Transaction]
|
||||
The transaction type =Tx= encapsulates a single transaction under consideration
|
||||
### Transaction
|
||||
|
||||
The transaction type `Tx` encapsulates a single transaction under consideration
|
||||
by consensus.
|
||||
|
||||
```
|
||||
```{.cpp}
|
||||
struct Tx
|
||||
{
|
||||
using ID = ...;
|
||||
@@ -407,13 +405,14 @@ struct Tx
|
||||
};
|
||||
```
|
||||
|
||||
[heading 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
|
||||
### 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
|
||||
(typically from peers) and can be modified to add or remove transactions via
|
||||
the mutable subtype.
|
||||
|
||||
```
|
||||
```{.cpp}
|
||||
struct TxSet
|
||||
{
|
||||
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
|
||||
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
|
||||
to know that peers are working on the same tip of the ledger chain and to
|
||||
provide some basic timing data for consensus.
|
||||
|
||||
```
|
||||
```{.cpp}
|
||||
struct Ledger
|
||||
{
|
||||
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
|
||||
generic =ConsensusProposal=.
|
||||
```
|
||||
generic `ConsensusProposal`.
|
||||
|
||||
```{.cpp}
|
||||
// Represents our proposed position or a peer's proposed position
|
||||
// and is provided with the generic code
|
||||
template <class NodeID_t, class LedgerID_t, class Position_t> class ConsensusProposal;
|
||||
@@ -502,15 +506,16 @@ struct PeerPosition
|
||||
// ... 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.
|
||||
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
|
||||
interact with the concrete implementing class.
|
||||
|
||||
```
|
||||
```{.cpp}
|
||||
// Represents a transction under dispute this round
|
||||
template <class Tx_t, class NodeID_t> class DisputedTx;
|
||||
|
||||
@@ -583,11 +588,12 @@ public:
|
||||
// ... details
|
||||
};
|
||||
```
|
||||
[heading Adapting Generic Consensus]
|
||||
|
||||
### Adapting Generic Consensus
|
||||
|
||||
The stub below shows the set of callback/helper functions required in the implementing class.
|
||||
|
||||
```
|
||||
```{.cpp}
|
||||
struct Adaptor
|
||||
{
|
||||
using Ledger_t = Ledger;
|
||||
@@ -651,30 +657,27 @@ struct Adaptor
|
||||
The implementing class hides many details of the peer communication
|
||||
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
|
||||
faster than =LEDGER_GRANULARITY=.
|
||||
faster than `LEDGER_GRANULARITY`.
|
||||
* 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
|
||||
ledger is only conceptual from the perspective of the generic code---the
|
||||
initial position and transaction set are opaquely generated in a
|
||||
`Consensus::Result` instance returned from the =onClose= callback.
|
||||
* The calls to =acquireLedger= and =acquireTxSet= only have non-trivial return
|
||||
`Consensus::Result` instance returned from the `onClose` callback.
|
||||
* The calls to `acquireLedger` and `acquireTxSet` only have non-trivial return
|
||||
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
|
||||
servicing the request asynchronously. Due to legacy reasons, the two calls
|
||||
are not symmetric. =acquireTxSet= requires the host application to call
|
||||
=gotTxSet= when an asynchronous =acquire= completes. Conversely,
|
||||
=acquireLedger= will be called again later by the consensus code if it still
|
||||
are not symmetric. `acquireTxSet` requires the host application to call
|
||||
`gotTxSet` when an asynchronous `acquire` completes. Conversely,
|
||||
`acquireLedger` will be called again later by the consensus code if it still
|
||||
desires the ledger with the hope that the asynchronous acquisition is
|
||||
complete.
|
||||
|
||||
[endsect] [/Consensus Type Requirements]
|
||||
|
||||
[section Validation]
|
||||
## Validation
|
||||
|
||||
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_BRIEF = C++ Library
|
||||
PROJECT_LOGO =
|
||||
PROJECT_LOGO = images/LogoForDocumentation.png
|
||||
OUTPUT_DIRECTORY =
|
||||
CREATE_SUBDIRS = NO
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
@@ -125,6 +126,41 @@ INPUT = \
|
||||
../src/ripple/app/tx/applySteps.h \
|
||||
../src/ripple/app/tx/impl/InvariantCheck.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
|
||||
FILE_PATTERNS =
|
||||
@@ -136,12 +172,16 @@ EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
IMAGE_PATH = \
|
||||
./images/ \
|
||||
./images/consensus/ \
|
||||
../src/test/csf/ \
|
||||
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
USE_MDFILE_AS_MAINPAGE = ../src/README.md
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
@@ -168,8 +208,8 @@ IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = NO
|
||||
HTML_OUTPUT = dhtm
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html_doc
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
@@ -269,8 +309,8 @@ MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = temp/
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = temp
|
||||
XML_PROGRAMLISTING = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -346,7 +386,7 @@ DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_JAR_PATH = $(PLANTUML_JAR)
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
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:
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Overlay
|
||||