From 9c8e3776defae09c3eecf68f8bed0a72133ed3d5 Mon Sep 17 00:00:00 2001 From: seelabs Date: Tue, 13 Sep 2016 18:18:58 -0400 Subject: [PATCH 1/7] Set issuer fix switch date --- src/ripple/ledger/impl/View.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ripple/ledger/impl/View.cpp b/src/ripple/ledger/impl/View.cpp index e147602875..73961f15f1 100644 --- a/src/ripple/ledger/impl/View.cpp +++ b/src/ripple/ledger/impl/View.cpp @@ -47,8 +47,8 @@ bool amendmentRIPD1141 (NetClock::time_point const closeTime) NetClock::time_point const& amendmentRIPD1274SoTime () { using namespace std::chrono_literals; - // Fri Sep 16, 2016 10:00:00am PDT - static NetClock::time_point const soTime{527360400s}; + // Fri Sep 23, 2016 10:00:00am PDT + static NetClock::time_point const soTime{527965200s}; return soTime; } From ddaeae285595387d75f57cd7e208509a8e604a6b Mon Sep 17 00:00:00 2001 From: seelabs Date: Tue, 13 Sep 2016 18:33:40 -0400 Subject: [PATCH 2/7] Set version to 0.33.0-rc2 --- src/ripple/protocol/impl/BuildInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ripple/protocol/impl/BuildInfo.cpp b/src/ripple/protocol/impl/BuildInfo.cpp index 119c53e4aa..5278526f6e 100644 --- a/src/ripple/protocol/impl/BuildInfo.cpp +++ b/src/ripple/protocol/impl/BuildInfo.cpp @@ -34,7 +34,7 @@ char const* const versionString = // The build version number. You must edit this for each release // and follow the format described at http://semver.org/ // - "0.33.0-rc1" + "0.33.0-rc2" #if defined(DEBUG) || defined(SANITIZER) "+" From b2499c8fa015ac0121b81dcf8f1a92d9e1fd6a4b Mon Sep 17 00:00:00 2001 From: Miguel Portilla Date: Wed, 14 Sep 2016 21:01:35 -0400 Subject: [PATCH 3/7] Add Status page: * Make HTTP(S) requests on websocket ports reply with Status page * Fix isWebsocketUpgrade to compare case insensitive * Make websocket upgrades with no websocket protocols configured report error * Create unit test for unauthorized requets and the status page --- Builds/VisualStudio2015/RippleD.vcxproj | 4 + .../VisualStudio2015/RippleD.vcxproj.filters | 3 + src/ripple/rpc/impl/ServerHandlerImp.cpp | 115 +++++++++-- src/ripple/rpc/impl/ServerHandlerImp.h | 19 +- src/test/server/ServerStatus_test.cpp | 187 ++++++++++++++++++ src/unity/server_test_unity.cpp | 3 +- 6 files changed, 306 insertions(+), 25 deletions(-) create mode 100644 src/test/server/ServerStatus_test.cpp diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj index 7c6678c5f8..c3cd6323e9 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj +++ b/Builds/VisualStudio2015/RippleD.vcxproj @@ -4744,6 +4744,10 @@ True True + + True + True + True True diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters index 77c978491c..943c9c752b 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters @@ -5433,6 +5433,9 @@ test\rpc + + test\server + test\server diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index c180f95a9d..0919d9cdb7 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -39,8 +39,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -119,9 +121,9 @@ ServerHandlerImp::onHandoff (Session& session, { if(isWebsocketUpgrade(request)) { - Handoff handoff; if(session.port().protocol.count("wss2") > 0) { + Handoff handoff; auto const ws = session.websocketUpgrade(); auto is = std::make_shared(m_networkOPs, ws); is->getConsumer() = requestInboundEndpoint( @@ -135,7 +137,9 @@ ServerHandlerImp::onHandoff (Session& session, } if(session.port().protocol.count("wss") > 0) - return handoff; // Pass to websocket + return {}; // Pass to websocket + + return unauthorizedResponse(request); } if(session.port().protocol.count("peer") > 0) @@ -144,6 +148,9 @@ ServerHandlerImp::onHandoff (Session& session, std::move(request), remote_address); } + if (session.port().protocol.count("wss2") > 0 && isStatusRequest(request)) + return statusResponse(request); + // Pass to legacy onRequest return {}; } @@ -155,22 +162,30 @@ ServerHandlerImp::onHandoff (Session& session, boost::asio::ip::tcp::endpoint remote_address) -> Handoff { - Handoff handoff; - if(session.port().protocol.count("ws2") > 0 && - isWebsocketUpgrade (request)) + if(isWebsocketUpgrade(request)) { - auto const ws = session.websocketUpgrade(); - auto is = std::make_shared(m_networkOPs, ws); - is->getConsumer() = requestInboundEndpoint( - m_resourceManager, - beast::IPAddressConversion::from_asio(remote_address), - session.port(), is->user()); - ws->appDefined = std::move(is); - ws->run(); - handoff.moved = true; + if (session.port().protocol.count("ws2") > 0) + { + Handoff handoff; + auto const ws = session.websocketUpgrade(); + auto is = std::make_shared(m_networkOPs, ws); + is->getConsumer() = requestInboundEndpoint( + m_resourceManager, beast::IPAddressConversion::from_asio( + remote_address), session.port(), is->user()); + ws->appDefined = std::move(is); + ws->run(); + handoff.moved = true; + return handoff; + } + + return unauthorizedResponse(request); } + + if (session.port().protocol.count("ws2") > 0 && isStatusRequest(request)) + return statusResponse(request); + // Otherwise pass to legacy onRequest or websocket - return handoff; + return {}; } static inline @@ -619,17 +634,81 @@ ServerHandlerImp::processRequest (Port const& port, // Returns `true` if the HTTP request is a Websockets Upgrade // http://en.wikipedia.org/wiki/HTTP/1.1_Upgrade_header#Use_with_WebSockets bool -ServerHandlerImp::isWebsocketUpgrade (http_request_type const& request) +ServerHandlerImp::isWebsocketUpgrade( + http_request_type const& request) const { if (is_upgrade(request)) - return request.headers["Upgrade"] == "websocket"; + return beast::detail::ci_equal( + request.headers["Upgrade"], "websocket"); return false; } +bool +ServerHandlerImp::isStatusRequest( + http_request_type const& request) const +{ + return request.version >= 11 && request.url == "/" && + request.body.size() == 0 && request.method == "GET"; +} + +/* This response is used with load balancing. + If the server is overloaded, status 500 is reported. Otherwise status 200 + is reported, meaning the server can accept more connections. +*/ +Handoff +ServerHandlerImp::statusResponse( + http_request_type const& request) const +{ + using namespace beast::http; + Handoff handoff; + response_v1 msg; + std::string reason; + if (app_.serverOkay(reason)) + { + msg.status = 200; + msg.reason = "OK"; + msg.body = "" + systemName() + + " Test page for rippled

" + + systemName() + " Test

This page shows rippled http(s) " + "connectivity is working.

"; + } + else + { + msg.status = 500; + msg.reason = "Internal Server Error"; + msg.body = "Server cannot accept clients: " + + reason + ""; + } + msg.version = request.version; + msg.headers.insert("Server", BuildInfo::getFullVersionString()); + msg.headers.insert("Content-Type", "text/html"); + prepare(msg, beast::http::connection::close); + handoff.response = std::make_shared(msg); + return handoff; +} + +Handoff +ServerHandlerImp::unauthorizedResponse( + http_request_type const& request) const +{ + using namespace beast::http; + Handoff handoff; + response_v1 msg; + msg.version = request.version; + msg.status = 401; + msg.reason = "Unauthorized"; + msg.headers.insert("Server", BuildInfo::getFullVersionString()); + msg.headers.insert("Content-Type", "text/html"); + msg.body = "Invalid protocol."; + prepare(msg, beast::http::connection::close); + handoff.response = std::make_shared(msg); + return handoff; +} + // VFALCO TODO Rewrite to use beast::http::headers bool ServerHandlerImp::authorized (Port const& port, - std::map const& h) + std::map const& h) const { if (port.user.empty() || port.password.empty()) return true; diff --git a/src/ripple/rpc/impl/ServerHandlerImp.h b/src/ripple/rpc/impl/ServerHandlerImp.h index de33b8b153..f42d7fffdc 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.h +++ b/src/ripple/rpc/impl/ServerHandlerImp.h @@ -149,8 +149,7 @@ public: void onStopped (Server&); - //-------------------------------------------------------------------------- - +private: Json::Value processSession( std::shared_ptr const& session, @@ -167,13 +166,21 @@ public: std::shared_ptr jobCoro, std::string forwardedFor, std::string user); -private: bool - isWebsocketUpgrade (http_request_type const& request); + isWebsocketUpgrade(http_request_type const& request) const; bool - authorized (Port const& port, - std::map const& h); + isStatusRequest(http_request_type const& request) const; + + Handoff + statusResponse(http_request_type const& request) const; + + Handoff + unauthorizedResponse(http_request_type const& request) const; + + bool + authorized (Port const& port, std::map const& h) const; }; } diff --git a/src/test/server/ServerStatus_test.cpp b/src/test/server/ServerStatus_test.cpp new file mode 100644 index 0000000000..3a1f69d0b1 --- /dev/null +++ b/src/test/server/ServerStatus_test.cpp @@ -0,0 +1,187 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + 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. +*/ +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ripple { +namespace test { + +class ServerStatus_test : public beast::unit_test::suite +{ +public: + void + testUnauthorizedRequest() + { + using namespace jtx; + Env env(*this, []() + { + auto p = std::make_unique(); + setupConfigForUnitTests(*p); + p->section("port_ws").set("protocol", "http,https"); + return p; + }()); + auto const port = env.app().config()["port_ws"]. + get("port"); + if(! expect(port)) + return; + + using namespace boost::asio; + using namespace beast::http; + io_service ios; + ip::tcp::resolver r{ios}; + beast::streambuf sb; + response_v1 resp; + boost::system::error_code ec; + + beast::websocket::detail::maskgen maskgen; + request_v1 req; + req.url = "/"; + req.version = 11; + req.method = "GET"; + req.headers.insert("Host", "127.0.0.1:" + to_string(*port)); + req.headers.insert("Upgrade", "websocket"); + std::string key = beast::websocket::detail::make_sec_ws_key(maskgen); + req.headers.insert("Sec-WebSocket-Key", key); + req.headers.insert("Sec-WebSocket-Version", "13"); + prepare(req, connection::upgrade); + + // non secure socket + { + ip::tcp::socket sock{ios}; + connect(sock, r.resolve( + ip::tcp::resolver::query{"127.0.0.1", to_string(*port)}), ec); + if(! expect(! ec)) + return; + write(sock, req, ec); + if(! expect(! ec)) + return; + read(sock, sb, resp, ec); + if(! expect(! ec)) + return; + expect(resp.status == 401); + } + + // secure socket + { + ssl::context ctx{ssl::context::sslv23}; + ctx.set_verify_mode(ssl::verify_none); + ssl::stream ss{ios, ctx}; + connect(ss.next_layer(), r.resolve( + ip::tcp::resolver::query{"127.0.0.1", to_string(*port)})); + ss.handshake(ssl::stream_base::client, ec); + if(! expect(! ec)) + return; + write(ss, req, ec); + if(! expect(! ec)) + return; + read(ss, sb, resp, ec); + if(! expect(! ec)) + return; + expect(resp.status == 401); + } + } + + void + testStatusRequest() + { + using namespace jtx; + Env env(*this, []() + { + auto p = std::make_unique(); + setupConfigForUnitTests(*p); + p->section("port_ws").set("protocol", "ws2,wss2"); + return p; + }()); + auto const port = env.app().config()["port_ws"]. + get("port"); + if(! expect(port)) + return; + + using namespace boost::asio; + using namespace beast::http; + io_service ios; + ip::tcp::resolver r{ios}; + beast::streambuf sb; + response_v1 resp; + boost::system::error_code ec; + + request_v1 req; + req.url = "/"; + req.version = 11; + req.method = "GET"; + req.headers.insert("Host", "127.0.0.1:" + to_string(*port)); + req.headers.insert("User-Agent", "test"); + prepare(req); + + // Request the status page on a non secure socket + { + ip::tcp::socket sock{ios}; + connect(sock, r.resolve( + ip::tcp::resolver::query{"127.0.0.1", to_string(*port)}), ec); + if(! expect(! ec)) + return; + write(sock, req, ec); + if(! expect(! ec)) + return; + read(sock, sb, resp, ec); + if(! expect(! ec)) + return; + expect(resp.status == 200); + } + + // Request the status page on a secure socket + { + ssl::context ctx{ssl::context::sslv23}; + ctx.set_verify_mode(ssl::verify_none); + ssl::stream ss{ios, ctx}; + connect(ss.next_layer(), r.resolve( + ip::tcp::resolver::query{"127.0.0.1", to_string(*port)})); + ss.handshake(ssl::stream_base::client, ec); + if(! expect(! ec)) + return; + write(ss, req, ec); + if(! expect(! ec)) + return; + read(ss, sb, resp, ec); + if(! expect(! ec)) + return; + expect(resp.status == 200); + } + }; + + void + run() + { + testUnauthorizedRequest(); + testStatusRequest(); + }; +}; + +BEAST_DEFINE_TESTSUITE(ServerStatus, server, ripple); + +} // test +} // ripple + diff --git a/src/unity/server_test_unity.cpp b/src/unity/server_test_unity.cpp index 1d52762897..1cb2570f1e 100644 --- a/src/unity/server_test_unity.cpp +++ b/src/unity/server_test_unity.cpp @@ -18,4 +18,5 @@ */ //============================================================================== -#include \ No newline at end of file +#include +#include From 076658e0f6d209e532437ce3a7c190abbdeb28d9 Mon Sep 17 00:00:00 2001 From: seelabs Date: Tue, 20 Sep 2016 15:12:58 -0400 Subject: [PATCH 4/7] Set issuer fix switch date --- src/ripple/ledger/impl/View.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ripple/ledger/impl/View.cpp b/src/ripple/ledger/impl/View.cpp index 73961f15f1..4e05353040 100644 --- a/src/ripple/ledger/impl/View.cpp +++ b/src/ripple/ledger/impl/View.cpp @@ -47,8 +47,9 @@ bool amendmentRIPD1141 (NetClock::time_point const closeTime) NetClock::time_point const& amendmentRIPD1274SoTime () { using namespace std::chrono_literals; - // Fri Sep 23, 2016 10:00:00am PDT - static NetClock::time_point const soTime{527965200s}; + // Fri Sep 30, 2016 10:00:00am PDT + static NetClock::time_point const soTime{528570000s}; + return soTime; } From bdbb3caf47d4faafd19876ee6974dabd11f35d5f Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Wed, 21 Sep 2016 12:11:44 -0700 Subject: [PATCH 5/7] Set version to 0.33.0-rc3 --- src/ripple/protocol/impl/BuildInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ripple/protocol/impl/BuildInfo.cpp b/src/ripple/protocol/impl/BuildInfo.cpp index 5278526f6e..a56dfe3db7 100644 --- a/src/ripple/protocol/impl/BuildInfo.cpp +++ b/src/ripple/protocol/impl/BuildInfo.cpp @@ -34,7 +34,7 @@ char const* const versionString = // The build version number. You must edit this for each release // and follow the format described at http://semver.org/ // - "0.33.0-rc2" + "0.33.0-rc3" #if defined(DEBUG) || defined(SANITIZER) "+" From 8734458cfb4bf703fd347eea26770c16c73cbfde Mon Sep 17 00:00:00 2001 From: johannakate Date: Fri, 9 Sep 2016 13:07:28 -0700 Subject: [PATCH 6/7] add the getInfoRippled.sh support script: The script can be used to quickly and easily retrieve information to assess the health of a rippled server --- bin/getInfoRippled.sh | 84 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 bin/getInfoRippled.sh diff --git a/bin/getInfoRippled.sh b/bin/getInfoRippled.sh new file mode 100644 index 0000000000..aa759729c9 --- /dev/null +++ b/bin/getInfoRippled.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash + +rippled_exe=/opt/ripple/bin/rippled +conf_file=/etc/opt/ripple/rippled.cfg + +while getopts ":e:c:" opt; do + case $opt in + e) + rippled_exe=${OPTARG} + ;; + c) + conf_file=${OPTARG} + ;; + \?) + echo "Invalid option: -$OPTARG" + esac +done + +tmp_loc=$(mktemp -d --tmpdir ripple_info.XXXX) +cd /tmp +chmod 751 ripple_info.* +cd ~ +echo ${tmp_loc} + +cleaned_conf=${tmp_loc}/cleaned_rippled_cfg.txt + +if [[ -f ${conf_file} ]] +then + db=$(sed -r -e 's/\/secretsecretsecretsecretmaybe/g' ${conf_file} |\ + awk -v OUT_FILE=${cleaned_conf} ' + BEGIN {skip=0; db_path="";print > OUT_FILE} + /^\[validation_seed\]/ {skip=1; next} + /^\[node_seed\]/ {skip=1; next} + /^\[.*\]/ {skip=0} + skip==1 {next} + save==1 {save=0;db_path=$0} + /^\[database_path\]/ {save=1} + {print >> OUT_FILE} + END {print db_path} + ') +fi + +echo "database_path: ${db}" +df ${db} > ${tmp_loc}/db_path_df.txt +echo + +# Send output from this script to a log file +## this captures any messages +## or errors from the script itself + +log_file=${tmp_loc}/get_info.log +exec 3>&1 1>>${log_file} 2>&1 + +## Send all stdout files to /tmp + +if [[ -x ${rippled_exe} ]] +then + pgrep rippled && \ + ${rippled_exe} --conf ${conf_file} \ + -- server_info > ${tmp_loc}/server_info.txt +fi + +df -h > ${tmp_loc}/free_disk_space.txt +cat /proc/meminfo > ${tmp_loc}/amount_mem.txt +cat /proc/swaps > ${tmp_loc}/swap_space.txt +ulimit -a > ${tmp_loc}/reported_current_limits.txt + +for dev_path in $(df | awk '$1 ~ /^\/dev\// {print $1}'); do + # strip numbers from end and remove '/dev/' + dev=$(basename ${dev_path%%[0-9]}) + if [[ "$(cat /sys/block/${dev}/queue/rotational)" = 0 ]] + then + echo "${dev} : SSD" >> ${tmp_loc}/is_ssd.txt + else + echo "${dev} : NO SSD" >> ${tmp_loc}/is_ssd.txt + fi +done + +pushd ${tmp_loc} +tar -czvf info-package.tar.gz *.txt *.log +popd + +echo "Use the following command on your local machine to download from your rippled instance: scp @:${tmp_loc}/info-package.tar.gz "| tee /dev/fd/3 + From f05321d501002cd7b8e7fba3ef361834689b3c26 Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Thu, 29 Sep 2016 09:25:46 -0700 Subject: [PATCH 7/7] Set version to 0.33.0 --- RELEASENOTES.md | 49 ++++++++++++++++++++++++++ src/ripple/protocol/impl/BuildInfo.cpp | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a6426092cc..4c0fd0675d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -6,6 +6,55 @@ run a `rippled` server, visit https://ripple.com/build/rippled-setup/ # Releases +## Version 0.33.0 + +The `rippled` 0.33.0 release includes an improved version of the payment code, which we expect to be activated via Amendment on Wednesday, 2016-10-20 with the name [Flow](https://ripple.com/build/amendments/#flow). We are also introducing XRP Payment Channels, a new structure in the ledger designed to support [Interledger Protocol](https://interledger.org/) trust lines as balances get substantial, which we expect to be activated via Amendment on a future date (TBA) with the name [PayChan](https://ripple.com/build/amendments/#paychan). Lastly, we will be introducing changes to the hash tree structure that rippled uses to represent a ledger, which we expect to be available via Amendment on a future date (TBA) with the name [SHAMapV2](https://ripple.com/build/amendments/#shamapv2). + +You can [update to the new version](https://ripple.com/build/rippled-setup/#updating-rippled) on Red Hat Enterprise Linux 7 or CentOS 7 using yum. For other platforms, please [compile the new version from source](https://wiki.ripple.com/Rippled_build_instructions). + +** New and Updated Features ** + +A fixed version of the new payment processing engine, which we initially announced on Friday, 2016-07-29, is expected to be available via Amendment on Wednesday, 2016-10-20 with the name [Flow](https://ripple.com/build/amendments/#flow). The new payments code adds no new features, but improves efficiency and robustness in payment handling. + +The Flow code may occasionally produce slightly different results than the old payment processing engine due to the effects of floating point rounding. + +We will be introducing changes to the hash tree structure that rippled uses to represent a ledger, which we expect to be activated via Amendment on a future date (TBA) with the name [SHAMapV2](https://ripple.com/build/amendments/#shamapv2). The new structure is more compact and efficient than the previous version. This affects how ledger hashes are calculated, but has no other user-facing consequences. The activation of the SHAMapV2 amendment will require brief scheduled allowable downtime, while the changes to the hash tree structure are propagated by the network. We will keep the community updated as we progress towards this date (TBA). + +In an effort to make RCL more scalable and to support Interledger Protocol (ILP) trust lines as balances get more substantial, we’re introducing XRP Payment Channels, a new structure in the ledger, which we expect to be available via Amendment on a future date (TBA) with the name [PayChan](https://ripple.com/build/amendments/#paychan). + +XRP Payment Channels permit scalable, intermittent, off-ledger settlement of ILP trust lines for high volume payments flowing in a single direction. For bidirectional channels, an XRP Payment Channel can be used in each direction. The recipient can claim any unpaid balance at any time. The owner can top off the channel as needed. The owner must wait out a delay to close the channel to give the recipient a chance to supply any claims. The total amount paid increases monotonically as newer claims are issued. + +The initial concept behind payment channels was discussed as early as 2011 and the first implementation was done by Mike Hearn in bitcoinj. Recent work being done by Lightning Network has showcased examples of the many use cases for payment channels. The introduction of XRP Payment Channels allows for a more efficient integration between RCL and ILP to further support enterprise use cases for high volume payments. + +Added `getInfoRippled.sh` support script to gather health check for rippled servers [RIPD-1284] + +The `account_info` command can now return information about queued transactions - [RIPD-1205] + +Automatically-provided sequence numbers now consider the transaction queue - [RIPD-1206] + +The `server_info` and `server_state` commands now include the queue-related escalated fee factor in the load_factor field of the response - [RIPD-1207] + +A transaction with a high transaction cost can now cause transactions from the same sender queued in front of it to get into the open ledger if the transaction costs are high enough on average across all such transactions. - [RIPD-1246] + +Reorganization: Move `LoadFeeTrack` to app/tx and clean up functions - [RIPD-956] + +Reorganization: unit test source files - [RIPD-1132] + +Reorganization: NuDB stand-alone repository - [RIPD-1163] + +Reorganization: Add `BEAST_EXPECT` to Beast - [RIPD-1243] + +Reorganization: Beast 64-bit CMake/Bjam target on Windows - [RIPD-1262] + +** Bug Fixes ** + +`PaymentSandbox::balanceHook` can return the wrong issuer, which could cause the transfer fee to be incorrectly by-passed in rare circumstances. [RIPD-1274, #1827] + +Prevent concurrent write operations in websockets [#1806] + +Add HTTP status page for new websocket implementation [#1855] + + ## Version 0.32.1 The `rippled` 0.32.1 release includes an improved version of the payment code, which we expect to be available via Amendment on Wednesday, 2016-08-24 with the name FlowV2, and a completely new implementation of the WebSocket protocol for serving clients. diff --git a/src/ripple/protocol/impl/BuildInfo.cpp b/src/ripple/protocol/impl/BuildInfo.cpp index a56dfe3db7..deef073ec5 100644 --- a/src/ripple/protocol/impl/BuildInfo.cpp +++ b/src/ripple/protocol/impl/BuildInfo.cpp @@ -34,7 +34,7 @@ char const* const versionString = // The build version number. You must edit this for each release // and follow the format described at http://semver.org/ // - "0.33.0-rc3" + "0.33.0" #if defined(DEBUG) || defined(SANITIZER) "+"