rippled
ValidatorSite_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright 2016 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/misc/ValidatorSite.h>
21 #include <ripple/basics/Slice.h>
22 #include <ripple/basics/base64.h>
23 #include <ripple/basics/strHex.h>
24 #include <ripple/protocol/HashPrefix.h>
25 #include <ripple/protocol/PublicKey.h>
26 #include <ripple/protocol/SecretKey.h>
27 #include <ripple/protocol/Sign.h>
28 #include <ripple/protocol/digest.h>
29 #include <ripple/protocol/jss.h>
30 #include <boost/algorithm/string/join.hpp>
31 #include <boost/algorithm/string/predicate.hpp>
32 #include <boost/asio.hpp>
33 #include <boost/range/adaptor/transformed.hpp>
34 #include <chrono>
35 #include <test/jtx.h>
36 #include <test/jtx/TrustedPublisherServer.h>
37 #include <test/unit_test/FileDirGuard.h>
38 
39 namespace ripple {
40 namespace test {
41 namespace detail {
42 constexpr const char*
44 {
45  return R"vl({
46  "public_key": "ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734",
47  "manifest": "JAAAAAFxIe0md6v/0bM6xvvDBitx8eg5fBUF4cQsZNEa0bKP9z9HNHMh7V0AnEi5D4odY9X2sx+cY8B3OHNjJvMhARRPtTHmWnAhdkDFcg53dAQS1WDMQDLIs2wwwHpScrUnjp1iZwwTXVXXsaRxLztycioto3JgImGdukXubbrjeqCNU02f7Y/+6w0BcBJA3M0EOU+39hmB8vwfgernXZIDQ1+o0dnuXjX73oDLgsacwXzLBVOdBpSAsJwYD+nW8YaSacOHEsWaPlof05EsAg==",
48  "blob" : "eyJzZXF1ZW5jZSI6MzcsImV4cGlyYXRpb24iOjU5NDE3MjgwMCwidmFsaWRhdG9ycyI6W3sidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQ0OUY4RUI4MDcxRTI2RDRFMDY3MjM4RDYyRDY3Q0E2RUJGQjI5OEI0QTcyRENGQUQ1MzZBN0VDODkyNUM1MTlCIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMUorT3VBY2VKdFRnWnlPTll0WjhwdXY3S1l0S2N0ejYxVGFuN0lrbHhSbTNNaEFvZ01tUVRSQUZLLyttL1hXUWZKdlhUZU1jYWl5RjZna2hnQXNzZExPY2lJZGtZd1JBSWdOeFlhdkpQeUhBTnV4b2dRWTdSTkJQOXRab2daSnhGMXdacXptNGEzN0dnQ0lCT3ZiZVE4K1A0NkNDSWN5NFpDWkE1clpaKzkzSDBhS0paUTMrSUEwT091Y0JKQUFTVHBRS3RFSmtlcXdIeitqS1dOdldsMHNIUlFaU1NKdVlpTXl5VWE3eXRwc2V2Nk5Hb0ZuMWJOcFlUZ3ZzYVB4b3o3dkhza0RoMlo2Z2ViU0RDUkNBPT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVEODEwOEY3RDlFRTc3OURDMTA3NUVDM0NGOEVCOTAwNERERjg0Q0QwQTBGRjU3NzVDOUUzNzVDQ0FDREFBMzAyMiIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTJCQ1BmWjduZWR3UWRldzgrT3VRQk4zNFROQ2cvMWQxeWVOMXpLemFvd0luTWhBbHZQSkFOUWNSVVNOVVIrTmxadW80a0dwWUY4bDlwSFBQMVpST09VY05ZUmRrWXdSQUlnUldaWnVKTEFmM1NOTUdvRnlnVWx1K2VBRDUxWm9IRk1jeW9pY24wV0t1Y0NJR3c0bjljVkRQT0JHQzh3bEpEeTkyODJ4OVJkT3dvMWNvMmcrTlpsYy9ETmNCSkFLSmhLL2FtNkw3S0U0NTBOVnpocFZWb0w4T0ZNbzBtRnhrOEJERzZRTzJjU05NTjNPeXdmNDBEK0lsZXM5TFh4eHZ2UEI2Z1dTbVBsd0Y3ZE5SOUdBUT09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDdFM0JBRkY5MDFERTUyNUIwMEIyQzFGRTE5QUY0NDlBMDgwQjVGMzEwMEM2RUMxODJDODY3QUY2MUY3MTBGRkQiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUxK082LzVBZDVTV3dDeXdmNFpyMFNhQ0F0Zk1RREc3QmdzaG5yMkgzRVAvWE1oQTUrR0RKaDJBcFdLQ2gyTjVvbXg0RkFPRkVxWE1qcXkxSEo1RTdXQTNGck9ka2N3UlFJaEFNUmV6d2pUQUwzNWpwamoxNWpxb0hVdlJtNys3aUhwVTQ3YUtFNkhFQ2haQWlCU01JWmFNV3Y2cU5KSG5pWXBzWUh4NE9QUHBCb0NNTWRNVkFHZkZpOWZLM0FTUUUwVFlpSXNHdjAveWxwcUdFQmlMa2syWGpyQTgrK0FrenByOXZjVHRya0hpRERvMGNIS085bVJVTEFYZXNSck95RmI1UWNPMGwwVnN3ZXZENWpsc3drPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQ0NUU4MEEwNEQ3OUNCOURGMDBBRUJEODZEQ0RDMTY4NkQ2NDE5RUE5RTVFMEU3MUYxQTgxN0UwOEI1MDc2QTU1IiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMUY2QW9FMTV5NTN3Q3V2WWJjM0JhRzFrR2VxZVhnNXg4YWdYNEl0UWRxVlhNaEF4Wm8xNTdwY0I5ZGU2U21rN2hvSzN3TkNBcjRhRlp0ZkFQaTdDRTRtTkpsZGtjd1JRSWhBTGxWalhDZml5L210WEJXc050Nzd0NGpLY05FQnBSVjh6ditTcFU1bENoMEFpQmE4dm84eHhwdmlZbGY0emRHK25RaEIyT2dma1FaWlBNSE90N0NhWHpYZ1hBU1FMOE81cDA4M21nNEtLTDh1WmZNYVVxZGd6dUowR3RhMWx5VVdQY3RUUEN4WTEzNVh3SytuSkFkRnNJVUZOSjlNUGpucENtU2pZVnpWYTZNNS9uQWNBST0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVERDhDODg2NDI3OTVDRTY5QzVCNzgwRTAxNzAyQzM3MEY5NTA3RDBCNjQ0MzNGMTdFRkU3MEYyNjM3QTQwQURCNyIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTNZeUlaQ2VWem1uRnQ0RGdGd0xEY1BsUWZRdGtRejhYNytjUEpqZWtDdHQzTWhBbkZmcityOUJYZHNYRS9jQmxKTXlkL1hzTzFBNVhFWUNjdHJzdkxFWCtEbWRrY3dSUUloQU5SY1JNZzlTQVhvYU92SERaMmF2OVJ6RWFaYVZFTmZRaVZnc2krT3gzRjBBaUIyc25TSU9tNmM0L2luYnRVMFVtV0xRVHp1d2tPZFVGUElCOEF4OGRtR3VIQVNRTVVJZlhNajk2a2NGVFNKbk1GQy9tVy9BUThiS1hrRnJyazBDVVRGRkt3ZUVqVHErU1RyRmk2cUxMMk1UN252ZUd4c1hCQ2d6dGpjMHFHYXM5S0ZXZ009In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFREJERUI5MDFGN0M3NUQwRTIwQzZDNDJBRjAzQkUwREE0MDM3N0FGMTkzOUExOEIzQ0IzNjc5NjYxREQ1RjlGNzQiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUyOTY1QWZmSFhRNGd4c1FxOER2ZzJrQTNldkdUbWhpenl6WjVaaDNWK2ZkSE1oQWczY3lLTlBNUHFLZ1I3a0lpN2MvOEdML1lnZEJ0ZzRtU0FXdndtYWV2Vkdka1l3UkFJZ1d6RzhHcVlnM1lwd0RzOHhYYTlYcUxIc3M3NktUMnVBSFJoVVhGVlVxQ1FDSUcyRXZiRktueGV6UmQ5Y3BQSFN0MzJIWEsrUDQrYUwzcDIrdnFsQ3hSUjljQkpBYm9YVG1ZVGF5b2NBM3pmOWRXRVh0eWFlT0dDMWs1V2RZVVJ6UGxlZXZ2YWxSNHhWb1h6czM4aUdQeEZyL3BBOW5MK000ZHV1MEdLQ0hsVmlyK2ZCQWc9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURBMTc4NzFFNzJCMEM1NzBBQzQzNDVDNjBDRjAyQUZCQkI3NDBBNjMxQjdBRDBFMUU1NzMyMTY1NzREOUFFQTAyIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMmhlSEhuS3d4WENzUTBYR0RQQXErN3QwQ21NYmV0RGg1WE1oWlhUWnJxQW5NaEFvanl1emd0cmVRa3hRajhwckh4T3NiRGNGNWZ1NFhYYjBLeEVML1BxNUhoZGtjd1JRSWhBTmZQRExaUDQ3YUNXd3Q1a0JucDc1QnV1Q2dwOWM0QmZKUGQ2NlNGQ3c2MUFpQUp2ZWdCdnZQSXJlYytYT1N6S1JmaTV1dVhXeHRsOUV5cjJhUEJZWHZiUkhBU1FNVUxZRW83YmVSZm9VQ25qazFzVFl5WTkxdExJR0xnbm5hV1hoVW04MCt6czVJR2VnazhxaWpLQXRCT011QkM3MWxBQjRLaEpjK2RCMnJwTU9GYzVndz0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVERjQ2RUUyN0FEMEUxQTcxNEFGRUNEQTgxNkVBQjcxMTQ2MTRGQ0I5MkQwQ0I0RDk3QjZBODhFRDQzNDM0QUZDOSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTMwYnVKNjBPR25GSy9zMm9GdXEzRVVZVS9Ma3RETFRaZTJxSTdVTkRTdnlYTWhBdzBBVFdqVlR0NEZmZUtPN2t2NmZGZ2QvZ28yK2Q1QlN5VWNVUm1SV25UdGRrY3dSUUloQU13T2dEZWM3UVlZTm5nc3BnOTB3RXZWYnNvaDJ1eDE0UlBUdytHSGFYTmxBaUFMZ2ZFc3orQUY0ZXlYL1k1aTQ0VnJGakZGSU1XVWZPWmFRSnRzeHRlTTFYQVNRTE9hRjB0MlpwcVZLZDhKRVNRVlkrelU1NjdpQUFHMmFtVFBaeDk1ODc1UzlBNlBsK2tINVRHSE1BZVdqZ1dTcWZoM20ySEJKWDdOSWNYYjk4dnk5QUE9In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDZFNEM0MUU1OUZGQkVCNTE3MjZFNTQ0Njg1MDJGRTY0MzcyMzhGQTc4RUE1MTYzNEU3QkYwRDA5MTcxQUVFOEYiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUxdVRFSGxuL3ZyVVhKdVZFYUZBdjVrTnlPUHA0NmxGalRudncwSkZ4cnVqM01oQXV6dEdXYi9PaTEvVjVtNWR1aldyOUhtYktSeUs0WFlrK2ttdUZQU2dBRnJka1l3UkFJZ2ZRK0JnWFg2UWJsWnk0SDA1bzdHUFNJd3FTN1FRUlVXN2RxRjU0SUFpaU1DSUg0WGZMdzk1NmlFYW94Wk9rN0tjdGluMlg5aE1mYUxON3d5czl5QVVGb1pjQkpBdWVFaTg0WFIzTGwxR0xKV2FuVzFnMU1kVWovMFBBeEpidzZFRVFSdUczemRudVJITlhsZDZVWkFiSWtWY1AwenRmcXVsQnpqYmNzTERPS0ZFaWNTQmc9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCNkZDOEU4MDNFRThFREMyNzkzRjFFQzkxN0IyRUU0MUQzNTI1NTYxOERFQjkxRDNGOUIxRkM4OUI3NUQ0NTM5IiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMjIvSTZBUHVqdHduay9Ic2tYc3U1QjAxSlZZWTNya2RQNXNmeUp0MTFGT1hNaEE4VmR2SEZ5U2NCeVFHVFlOR2VPdkIwKzY3Z1dhcWVmY2Z2Ums1K0t3Z1YxZGtZd1JBSWdaRnVsTy9BaU1vY3puZzZpLzRCa2Z6VDdqOWx4RjRQUDF1ZmdyT1FhSjhzQ0lCWC9FOFpicG43dFdxZ0F5TnlXcFZQa2hGbWFVTXFFcnk4V29VVDFmZEdRY0JKQXY1MVJxSnhnZy9Wcm5yWndpTEsyRGMwQ0tiaUxQTzVISjRaTXNqZFBUMmdSYzk3cldrQVh1VjJMNlBORk81OXh5dW9hWm1TTWxaWXZxU0dQcGZGN0J3PT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVENjkxMzAzOTkyRkVDNjRFNkJDNEJBQ0QzNkFFNkU1QUVEQzIzRjI4NjFCNkQ4RUZCOUZENzdFRTNFQURFMzQzNSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTFwRXdPWkwreGs1cnhMck5OcTV1V3UzQ1B5aGh0dGp2dWYxMzdqNnQ0ME5YTWhBaTJBWEpRZ28vSnVXM3I3Zi82Q2NWc0dOMVltSWoxMUdpSUVTSEJuUVNrOGRrY3dSUUloQU5DREVReW1yZDZ2ZVQzb3VhY0Y2ZmhCcjV3THczR21YZzFyTUNMVnZCelpBaUE4dVdRK3RxZDQ2V21mQmV4alNCUTJKZDZVQUdkckh2amNDUTJaZ1Nvb0NuQVNRRmtIbCtENy9VM1dCeVlQMzg0K3BjRkRmMkdpNFdJUkhWVG81OGNxZGs1Q0Rpd2MxVDByRG9MaG1vNDFhM2YrZHNmdGZ3UjRhTW13RmNQWExucmpyQUk9In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFREFEMTY2NjdGMDE4NUREQkI3RkE2NUIyMkY0QjdEMzEwQkY1QzNFMkQ5QjgyM0ZCMDZBM0E0MUFGOEFDODNCQzEiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUydEZtWi9BWVhkdTMrbVd5TDB0OU1RdjF3K0xadUNQN0JxT2tHdmlzZzd3WE1oQXF3ZUUzUElTM0U0NEtoTXFLakt0YmtCZThIOEdiaXVvQVhBWURSb1ZSSG9ka1l3UkFJZ2FnR2tYdG93VXliZGx0S29qdjBsdnZmbHJsUTlJUm5QT2pla0Y2MGlIemdDSUNnNlpvY0lNemtVdXZPOTFCRW9ybUlXbVg0Ry9NR1QyenJvNkkvUHZCOFhjQkpBY0pMWGt0L3cva2N3RXZOaVptaTJpMm5NbjF3aVAzTFM5TkpqQlBqdThLRkxBTWcwTzl5ZFFUNjdVL0FMWU9lVFBUTzIvaTJZdzlPU2xpYnRxaGd6REE9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURDMjQ1MDI3QTUyRUU1MzE4MDk1NTk4RUMzQUI2NUZGNEEzQjlGOTQyOEUxMEIyRjNDNkYzOURFMTVBMTVDOTBBIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllM0NSUUo2VXU1VEdBbFZtT3c2dGwvMG83bjVRbzRRc3ZQRzg1M2hXaFhKQ25NaEEvOC85cktVZEE2MWovZklFUC9jcUxweEJsbUloUDJyZzFkN05hRVB5S1YrZGtjd1JRSWhBSXhFME0vRko1MHZmWlc2ZlBweTR5Q1p1bVk5bjBvYnJPb2pVa2ptNTVhMEFpQmo1Nk8wTXBvcEdvWTlIeEMvKzR3Tk8zNkhvN0U5Q1FlSHNuS3JlRGRzQVhBU1FJWVVkODFqYmlWVWxFVDRkR29HMnArY2YrMkdxRVhYNWZKTVNTeVgvcWUwWGZSNGNPKzRxbGdtak1RZENSREJXQUJIVnZkTi95WnlpL3JMMmMrV3JRYz0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVENDI0NkFBM0FFOUQyOTg2Mzk0NDgwMENDQTkxODI5RTQ0NDc0OThBMjBDRDlDMzk3M0E2QjU5MzQ2Qzc1QUI5NSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTFDUnFvNjZkS1lZNVJJQU15cEdDbmtSSFNZb2d6Wnc1YzZhMWswYkhXcmxYTWhBa20xbHowYzhRWFdmSjliMXZCNzJkTGFidzh3WUlkOE10bnBzSEhCRUM4cGRrWXdSQUlnUWxiNkhKNTNoc1RBZlZpZCtBT2RCVnZNRjdyYWhJS05MQkhVZ241MnpCRUNJR0xVcUZ1OGExQUFIUkpjVm9uS1lFbm1oSndiQ1hMbitqZTduYTFXRDEvb2NCSkFFNHZmdnJHU21aQzJ1QVVHbU01ZElCdG9TZ0VVZXkrMlZsZURZRXNjZTk0dHhZY2pSOFo3UUxOYWxpRDh3L2JENS9odllROG1lVjFXZzFqSkZOZTBDQT09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDJDMTQ2OEI0QTExRDI4MUY5M0VGMzM3Qzk1RTRBMDhERjAwMDBGREVGQjZEMEVBOUJDMDVGQkQ1RDYxQTFGNUEiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUwc0ZHaTBvUjBvSDVQdk0zeVY1S0NOOEFBUDN2dHREcW04QmZ2VjFob2ZXbk1oQWtNVW1DRDJhUG1nRkREUm1pbXZTaWNTSVNjdzZZTnI0MkR3NFJBZHdyT0Fka2N3UlFJaEFKRk9ITWc2cVRHOHY2MGRocmVuWVlrNmN3T2FSWHEwUk5tTGp5eUNpejVsQWlBZFUwWWtEVUpRaG5OOFJ5OHMrNnpUSkxpTkxidE04b08vY0xudXJWcFJNM0FTUUdBTGFySEFzSmtTWlF0R2RNMkFhUi9qb0ZLL2poRFU1NytsK1JTWWpyaS95ZEUyMERhS2Fud2tNRW9WbEJUZzdsWDRoWWpFbm1rcW83M3dJdGhMT0FRPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURBNTRDODVGOTEyMTlGRDI1OTEzNEI2QjEyNkFENjRBRTcyMDRCODFERDQwNTI1MTA2NTdFMUE1Njk3MjQ2QUQyIiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMmxUSVg1RWhuOUpaRTB0ckVtcldTdWNnUzRIZFFGSlJCbGZocFdseVJxMG5NaEFsOGNKZXJQdit2bzFCSzYxMXhWVHBHeGpqci9DdXhQVGdVOFVSTTRlVFo1ZGtZd1JBSWdkSzNjUVYyWS92aVpuZS9QYm9LU0tld25nVHVJTjJNNmM4YXp3cWMyMHVVQ0lBYzZHb05UK1AyWUJ5NDlnZGF1NFA3eVN3V29RWDVuZjlkUXhpUWF2NXdJY0JKQXFpQ0swZDZRUlpTcGlWSHA4TzlubEtYQ1NFaHNpU05jV2NFRm0vZkdoSkFuQU4wT3Y5SElOSWQxcHhyQm4yZEtSZWdMVHZZRzNCcGJ6Ly9ITGdFZERBPT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVEOUFFNEY1ODg3QkEwMjlFQjdDMDg4NDQ4NkQyM0NGMjgxOTc1Rjc3M0Y0NEJEMjEzMDU0MjE5ODgyQzQxMUNDNyIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTJhNVBXSWU2QXA2M3dJaEVodEk4OG9HWFgzYy9STDBoTUZRaG1JTEVFY3gzTWhBbUcyemd2OEZCWnNaSlU4YVBhcHdvOWNJcVF2NC9NU1Mxb1ZBNWVWTWl3TGRrWXdSQUlnRitMT2U0ZVkwZ3A5dHRxaDJnbnYrejc1T3FMeU9RTXBHUEFMZ20rTnRPc0NJQ0RYQlpWUHRwcm1CRGtCSmtQRlNuRTU1RDllS1lSSDh6L2lZMUV0cE5wbGNCSkFBREVXR1ZUODBPd2hkMWxoMkpzVS9vWmxtZU5GNVdON1l2bEI4bGxFeGFSS0VWQytHVzlXZytpTklRM3JtVjdQOGFOYVZ1YWFiRzAwZk9na2d6TmhEdz09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFREE4RDI5RjQwQ0VCMjg5OTU2MTc2NDFBM0JDNDI2OTJFMURFODgzMjE0RjYxMkZCQjYyMDg3QTE0OEU1RjZGOUEiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUybzBwOUF6cktKbFdGMlFhTzhRbWt1SGVpRElVOWhMN3RpQ0hvVWpsOXZtbk1oQW5ZblA3RWc2VmdObkVVVFJFMjlkNjRqUVQvaUJjV1RRdE5yVXp5RDZNSitka2N3UlFJaEFPRXNWNWFuVGtsb1NtVFpSYmltTXlCS3FIb0pZWGNCQmU4bExpUFlDN21VQWlBejJhTk9wZlEvMUx5Y1dsb0lNdmRoeHppbnE1WDdVYXMvdU9TYjl3aDhkM0FTUUxWa2ZwVy9HTzZ3ZFQ2QXV1U0o1NlR0TTM0M3BETkgraVN6eGx0SWZkclBpVXhUNXJmNGsyMWxRUXVQQ2xYbTkrU2ZLckNpVVhaSzdkajAvR1dUWVFnPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQzOEIwMjg4RUEyNDBCNENERUMxOEExQTYyODlFQjQ5MDA3RTRFQkMwREU5NDQ4MDNFQjdFRjE0MUM1NjY0MDczIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMDRzQ2lPb2tDMHpld1lvYVlvbnJTUUIrVHJ3TjZVU0FQcmZ2RkJ4V1pBYzNNaEFnT0tjdkl1Y2hhbHJady9nbFR1T3hWM0lPQ2Nwb3J4TUI3SnFBVnVwazFlZGtjd1JRSWhBT3ZSenBlK0lZWksxTXlJbklRWjg3SnZQMko4U0lYQ1haTVBCQ2RJVEJhbUFpQVNhdkpYaTlwd3M4ckRESlN4aEdNbG1FN3pJNWJTQThpdnRSQzlMZ3ErVVhBU1FEbDNlb3FMSUQrRVRKTk0remJNdXZ3dmNIRUl4ZUJaa1o5ZnA1akp2Nk9DVFB3bGo0VEpTdXkxYXZFV3FVWVMycml2NUR2bDJoYUZVb0NIZjR5YXdBQT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVERUUxMERDMzZBQ0Q5OTVDOEUwRTg2RTNDRDJGQkY4MzAxQTRBQzJCODg0N0I2MUExOTM1REU0OTczQjQwN0MwRSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTN1RU53MnJObVZ5T0RvYmp6UysvZ3dHa3JDdUlSN1lhR1RYZVNYTzBCOERuTWhBbVgwdmI3aitsZ0JqRmpiTjlSbEE4Nko3QU8yVm42SExxdU8zYWlzSzRtd2RrWXdSQUlnZnhCTG43aTRqZy9kaTBVMjVxNmtJYlZmVHpxYkEwU0NwUTBJNTdUT0ZrY0NJRk10SlFwRU5qQjJLMkVtdkJIUHZOY3d1U1BjM3ZzRWVxRTJyTkovY1Q1RGNCSkFmNjhYUEZ1NVJqQ2VMZ3BGSk03UEtGTGdvVjhlMW54TzVld2pxOVErVEFFR25GeVMwSU93ZjZwT090SVZNZFZlWHUxdjZwNGZoWFFrZGloSHQxeDZBZz09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDU4M0VDRDA2QzNCNzM2OTk4MEU2NUM3OEM0NDBBNTI5MzAwRjU1N0VEODEyNTYyODNGN0RENUFBMzUxM0EzMzQiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUxWVBzMEd3N2MybVlEbVhIakVRS1VwTUE5VmZ0Z1NWaWcvZmRXcU5ST2pOSE1oQXl1VW56WloxbjIvR2FUbUUxbTdIL3Y5WWxaeURFd0hZM2dTSFVBM0lDTDlka1l3UkFJZ0h4MlBIdmlkb04rNXlHOVdlQVMyazdud0lNOGFqeFFXNndqdnQ4a0JlbkFDSUROeFFQUWtEeURKSDlzZVM1QzYybUFhclFtZ2lOODlZUzNqaE50bnZFSXFjQkpBajdKaDBLYWMrYUpkcG9lcHUvK2VKS25uRlE3WUJ5WkI4ZU1aK1NTMXpMaEUrbGlwLzQ5cXFWTmNwQXhFcWZhR3R4SnpvREREMS9RYnVVN05PU1BrQ2c9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQ5NUM1MTcyQjJBRDdEMzk0MzRFRUJDNDM2QjY1QjNCQjdFNThENUMxQ0VGQzgyMEI2OTcyQUNBRDc3NkUyODZBIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMlZ4UmNyS3RmVGxEVHV2RU5yWmJPN2ZsalZ3Yzc4Z2d0cGNxeXRkMjRvYW5NaEFpcWNSZGUzTVFaMDc1ZmE0Wk5OeVJhWUpHTWRCTmtCbm4zYlFyS3NlQkRRZGtZd1JBSWdVK0xmY0U3MURQVnJPK0t0VUJqUTlEMnUway9QcjdsdWtPMW5QUmo2aFNBQ0lETkxZQy9KRmdvYkNzSWEwQkd3KzZiVW5PdzltZVUzRmRYZ1I3UTdTb3FKY0JKQVhRYWtPb1FuUHAzcGNMTDd6ZEtDUFVYNGIrL0ZDOVVuaHFwK085eFFGblJhQ1dWR21rNU1KT0lNczRXT1FkcE0xajNPZ1NzQUJtUnVDWFl2d28vbkR3PT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVEOTAxNjNEMkJGMEI3Nzg4OTA0QzRBNDExOEQ3RDk2ODkyMEU4NDdEODhCNzkxNzgzOTA4MzdERTNDQTI2MTU2MiIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTJRRmowcjhMZDRpUVRFcEJHTmZaYUpJT2hIMkl0NUY0T1FnMzNqeWlZVlluTWhBNzJWVFJpR2hrSkJ0cWdHSER6SGo3WWJDNitOc0VLckZITnVFL0xPM1RuNWRrWXdSQUlnZjhzK2ZZdDBsbHJLUTJxaVdQbkdtYjZxSlBvZThPbkNNM1ZTMjlYS2JZWUNJSEdubEo0T1RzMmRYdWdPNkJ0bzYzTnBEdnZxSitXSXdkWUtxWjZCaUJmemNCSkFHdk50a29nNHBmRTVkWlJ3bWljODdaQmVldW5PaDRZcEwwU0VSZHhXajQzQ3M5ODE1ekZKdVp5c1NhVVgyUi92ZEUyVktxdlNncXF0REVuck1vMm9Bdz09In1dfQ==",
49  "signature" : "9FF30EDC4DED7ABCD0D36389B7C716EED4B5E4F043902853534EBAC7BE966BB3813D5CF25E4DADA5E657CCF019FFD11847FD3CC44B5559A6FCEEE4C3DCFF8D0E",
50  "version": 1
51 }
52 )vl";
53 }
54 
55 auto constexpr default_expires = std::chrono::seconds{3600};
57 } // namespace detail
58 
59 class ValidatorSite_test : public beast::unit_test::suite
60 {
61 private:
63 
64  void
66  {
67  testcase("Config Load");
68 
69  using namespace jtx;
70 
71  Env env(*this);
72  auto trustedSites =
73  std::make_unique<ValidatorSite>(env.app(), env.journal);
74 
75  // load should accept empty sites list
76  std::vector<std::string> emptyCfgSites;
77  BEAST_EXPECT(trustedSites->load(emptyCfgSites));
78 
79  // load should accept valid validator site uris
80  std::vector<std::string> cfgSites({
81  "http://ripple.com/", "http://ripple.com/validators",
82  "http://ripple.com:8080/validators",
83  "http://207.261.33.37/validators",
84  "http://207.261.33.37:8080/validators",
85  "https://ripple.com/validators",
86  "https://ripple.com:443/validators",
87  "file:///etc/opt/ripple/validators.txt",
88  "file:///C:/Lib/validators.txt"
89 #if !_MSC_VER
90  ,
91  "file:///"
92 #endif
93  });
94  BEAST_EXPECT(trustedSites->load(cfgSites));
95 
96  // load should reject validator site uris with invalid schemes
97  std::vector<std::string> badSites({"ftp://ripple.com/validators"});
98  BEAST_EXPECT(!trustedSites->load(badSites));
99 
100  badSites[0] = "wss://ripple.com/validators";
101  BEAST_EXPECT(!trustedSites->load(badSites));
102 
103  badSites[0] = "ripple.com/validators";
104  BEAST_EXPECT(!trustedSites->load(badSites));
105 
106  // Host names are not supported for file URLs
107  badSites[0] = "file://ripple.com/vl.txt";
108  BEAST_EXPECT(!trustedSites->load(badSites));
109 
110  // Even local host names are not supported for file URLs
111  badSites[0] = "file://localhost/home/user/vl.txt";
112  BEAST_EXPECT(!trustedSites->load(badSites));
113 
114  // Nor IP addresses
115  badSites[0] = "file://127.0.0.1/home/user/vl.txt";
116  BEAST_EXPECT(!trustedSites->load(badSites));
117 
118  // File URL path can not be empty
119  badSites[0] = "file://";
120  BEAST_EXPECT(!trustedSites->load(badSites));
121 
122 #if _MSC_VER // Windows paths strip off the leading /, leaving the path empty
123  // File URL path can not be a directory
124  // (/ is the only path we can reasonably assume is a directory)
125  badSites[0] = "file:///";
126  BEAST_EXPECT(!trustedSites->load(badSites));
127 #endif
128  }
129 
131  {
134  bool ssl;
135  bool failFetch = false;
136  bool failApply = false;
137  int serverVersion = 1;
142  };
143  void
145  {
146  testcase << "Fetch list - "
147  << boost::algorithm::join(
148  paths |
149  boost::adaptors::transformed(
150  [](FetchListConfig const& cfg) {
151  return cfg.path +
152  (cfg.ssl ? " [https] v" : " [http] v") +
154  " " + cfg.msg;
155  }),
156  ", ");
157  using namespace jtx;
158  using namespace std::chrono_literals;
159 
160  Env env(*this);
161  auto& trustedKeys = env.app().validators();
162  env.timeKeeper().set(env.timeKeeper().now() + 30s);
163 
164  test::StreamSink sink;
165  beast::Journal journal{sink};
166 
167  PublicKey emptyLocalKey;
168  std::vector<std::string> emptyCfgKeys;
169  struct publisher
170  {
171  publisher(FetchListConfig const& c) : cfg{c}
172  {
173  }
176  std::string uri;
177  FetchListConfig const& cfg;
178  bool isRetry;
179  };
180  std::vector<publisher> servers;
181 
182  auto constexpr listSize = 20;
183  std::vector<std::string> cfgPublishers;
184 
185  for (auto const& cfg : paths)
186  {
187  servers.push_back(cfg);
188  auto& item = servers.back();
189  item.isRetry = cfg.path == "/bad-resource";
190  item.list.reserve(listSize);
191  while (item.list.size() < listSize)
192  item.list.push_back(TrustedPublisherServer::randomValidator());
193 
194  NetClock::time_point const expires =
195  env.timeKeeper().now() + cfg.expiresFromNow;
196  NetClock::time_point const effective2 =
197  expires - cfg.effectiveOverlap;
198  NetClock::time_point const expires2 =
199  effective2 + cfg.expiresFromNow;
200  item.server = make_TrustedPublisherServer(
201  env.app().getIOService(),
202  item.list,
203  expires,
204  {{effective2, expires2}},
205  cfg.ssl,
206  cfg.serverVersion);
207  cfgPublishers.push_back(strHex(item.server->publisherPublic()));
208 
209  std::stringstream uri;
210  uri << (cfg.ssl ? "https://" : "http://")
211  << item.server->local_endpoint() << cfg.path;
212  item.uri = uri.str();
213  }
214 
215  BEAST_EXPECT(
216  trustedKeys.load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
217 
218  // Normally, tests will only need a fraction of this time,
219  // but sometimes DNS resolution takes an inordinate amount
220  // of time, so the test will just wait.
221  auto sites = std::make_unique<ValidatorSite>(env.app(), journal, 12s);
222 
224  for (auto const& u : servers)
225  uris.push_back(u.uri);
226  sites->load(uris);
227  sites->start();
228  sites->join();
229 
230  auto const jv = sites->getJson();
231  for (auto const& u : servers)
232  {
233  for (auto const& val : u.list)
234  {
235  BEAST_EXPECT(
236  trustedKeys.listed(val.masterPublic) != u.cfg.failApply);
237  BEAST_EXPECT(
238  trustedKeys.listed(val.signingPublic) != u.cfg.failApply);
239  }
240 
241  Json::Value myStatus;
242  for (auto const& vs : jv[jss::validator_sites])
243  if (vs[jss::uri].asString().find(u.uri) != std::string::npos)
244  myStatus = vs;
245  BEAST_EXPECTS(
246  myStatus[jss::last_refresh_message].asString().empty() !=
247  u.cfg.failFetch,
248  to_string(myStatus) + "\n" + sink.messages().str());
249 
250  if (!u.cfg.msg.empty())
251  {
252  BEAST_EXPECTS(
253  sink.messages().str().find(u.cfg.msg) != std::string::npos,
254  sink.messages().str());
255  }
256 
257  if (u.cfg.expectedRefreshMin)
258  {
259  BEAST_EXPECTS(
260  myStatus[jss::refresh_interval_min].asInt() ==
261  u.cfg.expectedRefreshMin,
262  to_string(myStatus));
263  }
264 
265  if (u.cfg.failFetch)
266  {
267  using namespace std::chrono;
268  log << " -- Msg: "
269  << myStatus[jss::last_refresh_message].asString()
270  << std::endl;
271  std::stringstream nextRefreshStr{
272  myStatus[jss::next_refresh_time].asString()};
273  system_clock::time_point nextRefresh;
274  date::from_stream(nextRefreshStr, "%Y-%b-%d %T", nextRefresh);
275  BEAST_EXPECT(!nextRefreshStr.fail());
276  auto now = system_clock::now();
277  BEAST_EXPECTS(
278  nextRefresh <= now + (u.isRetry ? seconds{30} : minutes{5}),
279  "Now: " + to_string(now) + ", NR: " + nextRefreshStr.str());
280  }
281  }
282  }
283 
284  void
286  {
287  testcase << "File list - " << paths[0].first
288  << (paths.size() > 1 ? ", " + paths[1].first : "");
289 
290  using namespace jtx;
291 
292  Env env(*this);
293 
294  test::StreamSink sink;
295  beast::Journal journal{sink};
296 
297  struct publisher
298  {
299  std::string uri;
300  std::string expectMsg;
301  bool shouldFail;
302  };
303  std::vector<publisher> servers;
304 
305  for (auto const& cfg : paths)
306  {
307  servers.push_back({});
308  auto& item = servers.back();
309  item.shouldFail = !cfg.second.empty();
310  item.expectMsg = cfg.second;
311 
312  std::stringstream uri;
313  uri << "file://" << cfg.first;
314  item.uri = uri.str();
315  }
316 
317  auto sites = std::make_unique<ValidatorSite>(env.app(), journal);
318 
320  for (auto const& u : servers)
321  uris.push_back(u.uri);
322  sites->load(uris);
323  sites->start();
324  sites->join();
325 
326  for (auto const& u : servers)
327  {
328  auto const jv = sites->getJson();
329  Json::Value myStatus;
330  for (auto const& vs : jv[jss::validator_sites])
331  if (vs[jss::uri].asString().find(u.uri) != std::string::npos)
332  myStatus = vs;
333  BEAST_EXPECTS(
334  myStatus[jss::last_refresh_message].asString().empty() !=
335  u.shouldFail,
336  to_string(myStatus));
337  if (u.shouldFail)
338  {
339  BEAST_EXPECTS(
340  sink.messages().str().find(u.expectMsg) !=
341  std::string::npos,
342  sink.messages().str());
343  log << " -- Msg: "
344  << myStatus[jss::last_refresh_message].asString()
345  << std::endl;
346  }
347  }
348  }
349 
350  void
352  {
353  auto fullPath = [](detail::FileDirGuard const& guard) {
354  auto absPath = absolute(guard.file()).string();
355  if (absPath.front() != '/')
356  absPath.insert(absPath.begin(), '/');
357  return absPath;
358  };
359  {
360  // Create a file with a real validator list
362  *this, "test_val", "vl.txt", detail::realValidatorContents());
363  // Create a file with arbitrary content
364  detail::FileDirGuard hello(
365  *this, "test_val", "helloworld.txt", "Hello, world!");
366  // Create a file with malformed Json
368  *this,
369  "test_val",
370  "json.txt",
371  R"json({ "version": 2, "extra" : "value" })json");
372  auto const goodPath = fullPath(good);
373  auto const helloPath = fullPath(hello);
374  auto const jsonPath = fullPath(json);
375  auto const missingPath = jsonPath + ".bad";
376  testFileList({
377  {goodPath, ""},
378  {helloPath,
379  "Unable to parse JSON response from file://" + helloPath},
380  {jsonPath,
381  "Missing fields in JSON response from file://" + jsonPath},
382  {missingPath, "Problem retrieving from file://" + missingPath},
383  });
384  }
385  }
386 
387 public:
388  void
389  run() override
390  {
391  testConfigLoad();
392 
393  for (auto ssl : {true, false})
394  {
395  // fetch single site
396  testFetchList({{"/validators", "", ssl}});
397  testFetchList({{"/validators2", "", ssl}});
398  // fetch multiple sites
399  testFetchList({{"/validators", "", ssl}, {"/validators", "", ssl}});
401  {{"/validators", "", ssl}, {"/validators2", "", ssl}});
403  {{"/validators2", "", ssl}, {"/validators", "", ssl}});
405  {{"/validators2", "", ssl}, {"/validators2", "", ssl}});
406  // fetch single site with single redirects
407  testFetchList({{"/redirect_once/301", "", ssl}});
408  testFetchList({{"/redirect_once/302", "", ssl}});
409  testFetchList({{"/redirect_once/307", "", ssl}});
410  testFetchList({{"/redirect_once/308", "", ssl}});
411  // one redirect, one not
413  {{"/validators", "", ssl}, {"/redirect_once/302", "", ssl}});
415  {{"/validators2", "", ssl}, {"/redirect_once/302", "", ssl}});
416  // UNLs with a "gap" between validUntil of one and validFrom of the
417  // next
419  {{"/validators2",
420  "",
421  ssl,
422  false,
423  false,
424  1,
426  std::chrono::seconds{-90}}});
427  // fetch single site with undending redirect (fails to load)
429  {{"/redirect_forever/301",
430  "Exceeded max redirects",
431  ssl,
432  true,
433  true}});
434  // two that redirect forever
436  {{"/redirect_forever/307",
437  "Exceeded max redirects",
438  ssl,
439  true,
440  true},
441  {"/redirect_forever/308",
442  "Exceeded max redirects",
443  ssl,
444  true,
445  true}});
446  // one undending redirect, one not
448  {{"/validators", "", ssl},
449  {"/redirect_forever/302",
450  "Exceeded max redirects",
451  ssl,
452  true,
453  true}});
454  // one undending redirect, one not
456  {{"/validators2", "", ssl},
457  {"/redirect_forever/302",
458  "Exceeded max redirects",
459  ssl,
460  true,
461  true}});
462  // invalid redir Location
464  {{"/redirect_to/ftp://invalid-url/302",
465  "Invalid redirect location",
466  ssl,
467  true,
468  true}});
470  {{"/redirect_to/file://invalid-url/302",
471  "Invalid redirect location",
472  ssl,
473  true,
474  true}});
475  // invalid json
477  {{"/validators/bad",
478  "Unable to parse JSON response",
479  ssl,
480  true,
481  true}});
483  {{"/validators2/bad",
484  "Unable to parse JSON response",
485  ssl,
486  true,
487  true}});
488  // error status returned
490  {{"/bad-resource", "returned bad status", ssl, true, true}});
491  // location field missing
493  {{"/redirect_nolo/308",
494  "returned a redirect with no Location",
495  ssl,
496  true,
497  true}});
498  // json fields missing
500  {{"/validators/missing",
501  "Missing fields in JSON response",
502  ssl,
503  true,
504  true}});
506  {{"/validators2/missing",
507  "Missing fields in JSON response",
508  ssl,
509  true,
510  true}});
511  // timeout
512  testFetchList({{"/sleep/13", "took too long", ssl, true, true}});
513  // bad manifest format using known versions
514  // * Retrieves a v1 formatted list claiming version 2
516  {{"/validators", "Missing fields", ssl, true, true, 2}});
517  // * Retrieves a v2 formatted list claiming version 1
519  {{"/validators2", "Missing fields", ssl, true, true, 0}});
520  // bad manifest version
521  // Because versions other than 1 are treated as v2, the v1
522  // list won't have the blobs_v2 fields, and thus will claim to have
523  // missing fields
525  {{"/validators", "Missing fields", ssl, true, true, 4}});
527  {{"/validators2",
528  "1 unsupported version",
529  ssl,
530  false,
531  true,
532  4}});
533  using namespace std::chrono_literals;
534  // get expired validator list
536  {{"/validators",
537  "Applied 1 expired validator list(s)",
538  ssl,
539  false,
540  false,
541  1,
542  0s}});
544  {{"/validators2",
545  "Applied 1 expired validator list(s)",
546  ssl,
547  false,
548  false,
549  1,
550  0s,
551  -1s}});
552  // force an out-of-range validUntil value
554  {{"/validators",
555  "1 invalid validator list(s)",
556  ssl,
557  false,
558  true,
559  1,
561  // force an out-of-range validUntil value on the future list
562  // The first list is accepted. The second fails. The parser
563  // returns the "best" result, so this looks like a success.
565  {{"/validators2",
566  "",
567  ssl,
568  false,
569  false,
570  1,
572  299s}});
573  // force an out-of-range validFrom value
574  // The first list is accepted. The second fails. The parser
575  // returns the "best" result, so this looks like a success.
577  {{"/validators2",
578  "",
579  ssl,
580  false,
581  false,
582  1,
584  301s}});
585  // force an out-of-range validUntil value on _both_ lists
587  {{"/validators2",
588  "2 invalid validator list(s)",
589  ssl,
590  false,
591  true,
592  1,
595  // verify refresh intervals are properly clamped
597  {{"/validators/refresh/0",
598  "",
599  ssl,
600  false,
601  false,
602  1,
605  1}}); // minimum of 1 minute
607  {{"/validators2/refresh/0",
608  "",
609  ssl,
610  false,
611  false,
612  1,
615  1}}); // minimum of 1 minute
617  {{"/validators/refresh/10",
618  "",
619  ssl,
620  false,
621  false,
622  1,
625  10}}); // 10 minutes is fine
627  {{"/validators2/refresh/10",
628  "",
629  ssl,
630  false,
631  false,
632  1,
635  10}}); // 10 minutes is fine
637  {{"/validators/refresh/2000",
638  "",
639  ssl,
640  false,
641  false,
642  1,
645  60 * 24}}); // max of 24 hours
647  {{"/validators2/refresh/2000",
648  "",
649  ssl,
650  false,
651  false,
652  1,
655  60 * 24}}); // max of 24 hours
656  }
657  testFileURLs();
658  }
659 };
660 
662 
663 } // namespace test
664 } // namespace ripple
ripple::test::jtx::json
Inject raw JSON.
Definition: jtx_json.h:31
ripple::test::ValidatorSite_test::testConfigLoad
void testConfigLoad()
Definition: ValidatorSite_test.cpp:65
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
std::string
STL class.
ripple::test::ValidatorSite_test::FetchListConfig::ssl
bool ssl
Definition: ValidatorSite_test.cpp:134
std::shared_ptr
STL class.
ripple::ValidatorSite
Definition: ValidatorSite.h:69
std::pair
std::string::reserve
T reserve(T... args)
std::vector< std::string >
std::chrono::seconds
ripple::test::ValidatorSite_test::testFileURLs
void testFileURLs()
Definition: ValidatorSite_test.cpp:351
std::stringstream
STL class.
ripple::test::jtx::Env::journal
const beast::Journal journal
Definition: Env.h:143
ripple::test::jtx::Env::timeKeeper
ManualTimeKeeper & timeKeeper()
Definition: Env.h:252
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:240
std::vector::back
T back(T... args)
ripple::test::ValidatorSite_test::FetchListConfig::expectedRefreshMin
int expectedRefreshMin
Definition: ValidatorSite_test.cpp:141
ripple::test::detail::default_effective_overlap
constexpr auto default_effective_overlap
Definition: ValidatorSite_test.cpp:56
ripple::test::detail::realValidatorContents
constexpr const char * realValidatorContents()
Definition: ValidatorSite_test.cpp:43
std::vector::push_back
T push_back(T... args)
ripple::test::ValidatorSite_test::testFetchList
void testFetchList(std::vector< FetchListConfig > const &paths)
Definition: ValidatorSite_test.cpp:144
Json::Value::maxInt
static const Int maxInt
Definition: json_value.h:159
std::log
T log(T... args)
ripple::test::ValidatorSite_test::testFileList
void testFileList(std::vector< std::pair< std::string, std::string >> const &paths)
Definition: ValidatorSite_test.cpp:285
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
chrono
ripple::test::TrustedPublisherServer::Validator
Definition: TrustedPublisherServer.h:112
ripple::test::ValidatorSite_test::FetchListConfig::serverVersion
int serverVersion
Definition: ValidatorSite_test.cpp:137
std::to_string
T to_string(T... args)
ripple::test::ValidatorSite_test::FetchListConfig::path
std::string path
Definition: ValidatorSite_test.cpp:132
ripple::test::jtx::paths
Set Paths, SendMax on a JTx.
Definition: paths.h:32
std::chrono::time_point
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::test::TrustedPublisherServer::randomValidator
static Validator randomValidator()
Definition: TrustedPublisherServer.h:148
ripple::test::ValidatorSite_test::FetchListConfig::failFetch
bool failFetch
Definition: ValidatorSite_test.cpp:135
ripple::test::detail::default_expires
constexpr auto default_expires
Definition: ValidatorSite_test.cpp:55
ripple::test::ValidatorSite_test::FetchListConfig::effectiveOverlap
std::chrono::seconds effectiveOverlap
Definition: ValidatorSite_test.cpp:139
ripple::Application::validators
virtual ValidatorList & validators()=0
ripple::Application::getIOService
virtual boost::asio::io_service & getIOService()=0
ripple::test::StreamSink
Definition: SuiteJournal.h:114
ripple::test::StreamSink::messages
std::stringstream const & messages() const
Definition: SuiteJournal.h:134
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::endl
T endl(T... args)
ripple::test::ValidatorSite_test
Definition: ValidatorSite_test.cpp:59
ripple::test::ValidatorSite_test::FetchListConfig
Definition: ValidatorSite_test.cpp:130
ripple::test::ValidatorSite_test::FetchListConfig::expiresFromNow
std::chrono::seconds expiresFromNow
Definition: ValidatorSite_test.cpp:138
ripple::test::ValidatorSite_test::run
void run() override
Definition: ValidatorSite_test.cpp:389
ripple::test::ValidatorSite_test::FetchListConfig::failApply
bool failApply
Definition: ValidatorSite_test.cpp:136
ripple::test::make_TrustedPublisherServer
std::shared_ptr< TrustedPublisherServer > make_TrustedPublisherServer(boost::asio::io_context &ioc, std::vector< TrustedPublisherServer::Validator > const &validators, NetClock::time_point validUntil, std::vector< std::pair< NetClock::time_point, NetClock::time_point >> const &futures, bool useSSL=false, int version=1, bool immediateStart=true, int sequence=1)
Definition: TrustedPublisherServer.h:712
std::stringstream::str
T str(T... args)
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:38
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
ripple::test::detail::FileDirGuard
Write a file in a directory and remove when done.
Definition: FileDirGuard.h:110
ripple::test::ManualTimeKeeper::now
time_point now() const override
Returns the estimate of wall time, in network time.
Definition: ManualTimeKeeper.cpp:37
ripple::test::ManualTimeKeeper::set
void set(time_point now)
Definition: ManualTimeKeeper.cpp:81
ripple::test::ValidatorSite_test::FetchListConfig::msg
std::string msg
Definition: ValidatorSite_test.cpp:133
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:115
Json::Value
Represents a JSON value.
Definition: json_value.h:145
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
std::chrono
std::chrono::system_clock::now
T now(T... args)