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 <date/date.h>
36 #include <test/jtx.h>
37 #include <test/jtx/TrustedPublisherServer.h>
38 #include <test/unit_test/FileDirGuard.h>
39 
40 namespace ripple {
41 namespace test {
42 namespace detail {
43 constexpr const char*
45 {
46  return R"vl({
47  "public_key": "ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734",
48  "manifest": "JAAAAAFxIe0md6v/0bM6xvvDBitx8eg5fBUF4cQsZNEa0bKP9z9HNHMh7V0AnEi5D4odY9X2sx+cY8B3OHNjJvMhARRPtTHmWnAhdkDFcg53dAQS1WDMQDLIs2wwwHpScrUnjp1iZwwTXVXXsaRxLztycioto3JgImGdukXubbrjeqCNU02f7Y/+6w0BcBJA3M0EOU+39hmB8vwfgernXZIDQ1+o0dnuXjX73oDLgsacwXzLBVOdBpSAsJwYD+nW8YaSacOHEsWaPlof05EsAg==",
49  "blob" : "eyJzZXF1ZW5jZSI6MzcsImV4cGlyYXRpb24iOjU5NDE3MjgwMCwidmFsaWRhdG9ycyI6W3sidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQ0OUY4RUI4MDcxRTI2RDRFMDY3MjM4RDYyRDY3Q0E2RUJGQjI5OEI0QTcyRENGQUQ1MzZBN0VDODkyNUM1MTlCIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMUorT3VBY2VKdFRnWnlPTll0WjhwdXY3S1l0S2N0ejYxVGFuN0lrbHhSbTNNaEFvZ01tUVRSQUZLLyttL1hXUWZKdlhUZU1jYWl5RjZna2hnQXNzZExPY2lJZGtZd1JBSWdOeFlhdkpQeUhBTnV4b2dRWTdSTkJQOXRab2daSnhGMXdacXptNGEzN0dnQ0lCT3ZiZVE4K1A0NkNDSWN5NFpDWkE1clpaKzkzSDBhS0paUTMrSUEwT091Y0JKQUFTVHBRS3RFSmtlcXdIeitqS1dOdldsMHNIUlFaU1NKdVlpTXl5VWE3eXRwc2V2Nk5Hb0ZuMWJOcFlUZ3ZzYVB4b3o3dkhza0RoMlo2Z2ViU0RDUkNBPT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVEODEwOEY3RDlFRTc3OURDMTA3NUVDM0NGOEVCOTAwNERERjg0Q0QwQTBGRjU3NzVDOUUzNzVDQ0FDREFBMzAyMiIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTJCQ1BmWjduZWR3UWRldzgrT3VRQk4zNFROQ2cvMWQxeWVOMXpLemFvd0luTWhBbHZQSkFOUWNSVVNOVVIrTmxadW80a0dwWUY4bDlwSFBQMVpST09VY05ZUmRrWXdSQUlnUldaWnVKTEFmM1NOTUdvRnlnVWx1K2VBRDUxWm9IRk1jeW9pY24wV0t1Y0NJR3c0bjljVkRQT0JHQzh3bEpEeTkyODJ4OVJkT3dvMWNvMmcrTlpsYy9ETmNCSkFLSmhLL2FtNkw3S0U0NTBOVnpocFZWb0w4T0ZNbzBtRnhrOEJERzZRTzJjU05NTjNPeXdmNDBEK0lsZXM5TFh4eHZ2UEI2Z1dTbVBsd0Y3ZE5SOUdBUT09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDdFM0JBRkY5MDFERTUyNUIwMEIyQzFGRTE5QUY0NDlBMDgwQjVGMzEwMEM2RUMxODJDODY3QUY2MUY3MTBGRkQiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUxK082LzVBZDVTV3dDeXdmNFpyMFNhQ0F0Zk1RREc3QmdzaG5yMkgzRVAvWE1oQTUrR0RKaDJBcFdLQ2gyTjVvbXg0RkFPRkVxWE1qcXkxSEo1RTdXQTNGck9ka2N3UlFJaEFNUmV6d2pUQUwzNWpwamoxNWpxb0hVdlJtNys3aUhwVTQ3YUtFNkhFQ2haQWlCU01JWmFNV3Y2cU5KSG5pWXBzWUh4NE9QUHBCb0NNTWRNVkFHZkZpOWZLM0FTUUUwVFlpSXNHdjAveWxwcUdFQmlMa2syWGpyQTgrK0FrenByOXZjVHRya0hpRERvMGNIS085bVJVTEFYZXNSck95RmI1UWNPMGwwVnN3ZXZENWpsc3drPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQ0NUU4MEEwNEQ3OUNCOURGMDBBRUJEODZEQ0RDMTY4NkQ2NDE5RUE5RTVFMEU3MUYxQTgxN0UwOEI1MDc2QTU1IiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMUY2QW9FMTV5NTN3Q3V2WWJjM0JhRzFrR2VxZVhnNXg4YWdYNEl0UWRxVlhNaEF4Wm8xNTdwY0I5ZGU2U21rN2hvSzN3TkNBcjRhRlp0ZkFQaTdDRTRtTkpsZGtjd1JRSWhBTGxWalhDZml5L210WEJXc050Nzd0NGpLY05FQnBSVjh6ditTcFU1bENoMEFpQmE4dm84eHhwdmlZbGY0emRHK25RaEIyT2dma1FaWlBNSE90N0NhWHpYZ1hBU1FMOE81cDA4M21nNEtLTDh1WmZNYVVxZGd6dUowR3RhMWx5VVdQY3RUUEN4WTEzNVh3SytuSkFkRnNJVUZOSjlNUGpucENtU2pZVnpWYTZNNS9uQWNBST0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVERDhDODg2NDI3OTVDRTY5QzVCNzgwRTAxNzAyQzM3MEY5NTA3RDBCNjQ0MzNGMTdFRkU3MEYyNjM3QTQwQURCNyIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTNZeUlaQ2VWem1uRnQ0RGdGd0xEY1BsUWZRdGtRejhYNytjUEpqZWtDdHQzTWhBbkZmcityOUJYZHNYRS9jQmxKTXlkL1hzTzFBNVhFWUNjdHJzdkxFWCtEbWRrY3dSUUloQU5SY1JNZzlTQVhvYU92SERaMmF2OVJ6RWFaYVZFTmZRaVZnc2krT3gzRjBBaUIyc25TSU9tNmM0L2luYnRVMFVtV0xRVHp1d2tPZFVGUElCOEF4OGRtR3VIQVNRTVVJZlhNajk2a2NGVFNKbk1GQy9tVy9BUThiS1hrRnJyazBDVVRGRkt3ZUVqVHErU1RyRmk2cUxMMk1UN252ZUd4c1hCQ2d6dGpjMHFHYXM5S0ZXZ009In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFREJERUI5MDFGN0M3NUQwRTIwQzZDNDJBRjAzQkUwREE0MDM3N0FGMTkzOUExOEIzQ0IzNjc5NjYxREQ1RjlGNzQiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUyOTY1QWZmSFhRNGd4c1FxOER2ZzJrQTNldkdUbWhpenl6WjVaaDNWK2ZkSE1oQWczY3lLTlBNUHFLZ1I3a0lpN2MvOEdML1lnZEJ0ZzRtU0FXdndtYWV2Vkdka1l3UkFJZ1d6RzhHcVlnM1lwd0RzOHhYYTlYcUxIc3M3NktUMnVBSFJoVVhGVlVxQ1FDSUcyRXZiRktueGV6UmQ5Y3BQSFN0MzJIWEsrUDQrYUwzcDIrdnFsQ3hSUjljQkpBYm9YVG1ZVGF5b2NBM3pmOWRXRVh0eWFlT0dDMWs1V2RZVVJ6UGxlZXZ2YWxSNHhWb1h6czM4aUdQeEZyL3BBOW5MK000ZHV1MEdLQ0hsVmlyK2ZCQWc9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURBMTc4NzFFNzJCMEM1NzBBQzQzNDVDNjBDRjAyQUZCQkI3NDBBNjMxQjdBRDBFMUU1NzMyMTY1NzREOUFFQTAyIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMmhlSEhuS3d4WENzUTBYR0RQQXErN3QwQ21NYmV0RGg1WE1oWlhUWnJxQW5NaEFvanl1emd0cmVRa3hRajhwckh4T3NiRGNGNWZ1NFhYYjBLeEVML1BxNUhoZGtjd1JRSWhBTmZQRExaUDQ3YUNXd3Q1a0JucDc1QnV1Q2dwOWM0QmZKUGQ2NlNGQ3c2MUFpQUp2ZWdCdnZQSXJlYytYT1N6S1JmaTV1dVhXeHRsOUV5cjJhUEJZWHZiUkhBU1FNVUxZRW83YmVSZm9VQ25qazFzVFl5WTkxdExJR0xnbm5hV1hoVW04MCt6czVJR2VnazhxaWpLQXRCT011QkM3MWxBQjRLaEpjK2RCMnJwTU9GYzVndz0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVERjQ2RUUyN0FEMEUxQTcxNEFGRUNEQTgxNkVBQjcxMTQ2MTRGQ0I5MkQwQ0I0RDk3QjZBODhFRDQzNDM0QUZDOSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTMwYnVKNjBPR25GSy9zMm9GdXEzRVVZVS9Ma3RETFRaZTJxSTdVTkRTdnlYTWhBdzBBVFdqVlR0NEZmZUtPN2t2NmZGZ2QvZ28yK2Q1QlN5VWNVUm1SV25UdGRrY3dSUUloQU13T2dEZWM3UVlZTm5nc3BnOTB3RXZWYnNvaDJ1eDE0UlBUdytHSGFYTmxBaUFMZ2ZFc3orQUY0ZXlYL1k1aTQ0VnJGakZGSU1XVWZPWmFRSnRzeHRlTTFYQVNRTE9hRjB0MlpwcVZLZDhKRVNRVlkrelU1NjdpQUFHMmFtVFBaeDk1ODc1UzlBNlBsK2tINVRHSE1BZVdqZ1dTcWZoM20ySEJKWDdOSWNYYjk4dnk5QUE9In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDZFNEM0MUU1OUZGQkVCNTE3MjZFNTQ0Njg1MDJGRTY0MzcyMzhGQTc4RUE1MTYzNEU3QkYwRDA5MTcxQUVFOEYiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUxdVRFSGxuL3ZyVVhKdVZFYUZBdjVrTnlPUHA0NmxGalRudncwSkZ4cnVqM01oQXV6dEdXYi9PaTEvVjVtNWR1aldyOUhtYktSeUs0WFlrK2ttdUZQU2dBRnJka1l3UkFJZ2ZRK0JnWFg2UWJsWnk0SDA1bzdHUFNJd3FTN1FRUlVXN2RxRjU0SUFpaU1DSUg0WGZMdzk1NmlFYW94Wk9rN0tjdGluMlg5aE1mYUxON3d5czl5QVVGb1pjQkpBdWVFaTg0WFIzTGwxR0xKV2FuVzFnMU1kVWovMFBBeEpidzZFRVFSdUczemRudVJITlhsZDZVWkFiSWtWY1AwenRmcXVsQnpqYmNzTERPS0ZFaWNTQmc9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCNkZDOEU4MDNFRThFREMyNzkzRjFFQzkxN0IyRUU0MUQzNTI1NTYxOERFQjkxRDNGOUIxRkM4OUI3NUQ0NTM5IiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMjIvSTZBUHVqdHduay9Ic2tYc3U1QjAxSlZZWTNya2RQNXNmeUp0MTFGT1hNaEE4VmR2SEZ5U2NCeVFHVFlOR2VPdkIwKzY3Z1dhcWVmY2Z2Ums1K0t3Z1YxZGtZd1JBSWdaRnVsTy9BaU1vY3puZzZpLzRCa2Z6VDdqOWx4RjRQUDF1ZmdyT1FhSjhzQ0lCWC9FOFpicG43dFdxZ0F5TnlXcFZQa2hGbWFVTXFFcnk4V29VVDFmZEdRY0JKQXY1MVJxSnhnZy9Wcm5yWndpTEsyRGMwQ0tiaUxQTzVISjRaTXNqZFBUMmdSYzk3cldrQVh1VjJMNlBORk81OXh5dW9hWm1TTWxaWXZxU0dQcGZGN0J3PT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVENjkxMzAzOTkyRkVDNjRFNkJDNEJBQ0QzNkFFNkU1QUVEQzIzRjI4NjFCNkQ4RUZCOUZENzdFRTNFQURFMzQzNSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTFwRXdPWkwreGs1cnhMck5OcTV1V3UzQ1B5aGh0dGp2dWYxMzdqNnQ0ME5YTWhBaTJBWEpRZ28vSnVXM3I3Zi82Q2NWc0dOMVltSWoxMUdpSUVTSEJuUVNrOGRrY3dSUUloQU5DREVReW1yZDZ2ZVQzb3VhY0Y2ZmhCcjV3THczR21YZzFyTUNMVnZCelpBaUE4dVdRK3RxZDQ2V21mQmV4alNCUTJKZDZVQUdkckh2amNDUTJaZ1Nvb0NuQVNRRmtIbCtENy9VM1dCeVlQMzg0K3BjRkRmMkdpNFdJUkhWVG81OGNxZGs1Q0Rpd2MxVDByRG9MaG1vNDFhM2YrZHNmdGZ3UjRhTW13RmNQWExucmpyQUk9In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFREFEMTY2NjdGMDE4NUREQkI3RkE2NUIyMkY0QjdEMzEwQkY1QzNFMkQ5QjgyM0ZCMDZBM0E0MUFGOEFDODNCQzEiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUydEZtWi9BWVhkdTMrbVd5TDB0OU1RdjF3K0xadUNQN0JxT2tHdmlzZzd3WE1oQXF3ZUUzUElTM0U0NEtoTXFLakt0YmtCZThIOEdiaXVvQVhBWURSb1ZSSG9ka1l3UkFJZ2FnR2tYdG93VXliZGx0S29qdjBsdnZmbHJsUTlJUm5QT2pla0Y2MGlIemdDSUNnNlpvY0lNemtVdXZPOTFCRW9ybUlXbVg0Ry9NR1QyenJvNkkvUHZCOFhjQkpBY0pMWGt0L3cva2N3RXZOaVptaTJpMm5NbjF3aVAzTFM5TkpqQlBqdThLRkxBTWcwTzl5ZFFUNjdVL0FMWU9lVFBUTzIvaTJZdzlPU2xpYnRxaGd6REE9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURDMjQ1MDI3QTUyRUU1MzE4MDk1NTk4RUMzQUI2NUZGNEEzQjlGOTQyOEUxMEIyRjNDNkYzOURFMTVBMTVDOTBBIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllM0NSUUo2VXU1VEdBbFZtT3c2dGwvMG83bjVRbzRRc3ZQRzg1M2hXaFhKQ25NaEEvOC85cktVZEE2MWovZklFUC9jcUxweEJsbUloUDJyZzFkN05hRVB5S1YrZGtjd1JRSWhBSXhFME0vRko1MHZmWlc2ZlBweTR5Q1p1bVk5bjBvYnJPb2pVa2ptNTVhMEFpQmo1Nk8wTXBvcEdvWTlIeEMvKzR3Tk8zNkhvN0U5Q1FlSHNuS3JlRGRzQVhBU1FJWVVkODFqYmlWVWxFVDRkR29HMnArY2YrMkdxRVhYNWZKTVNTeVgvcWUwWGZSNGNPKzRxbGdtak1RZENSREJXQUJIVnZkTi95WnlpL3JMMmMrV3JRYz0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVENDI0NkFBM0FFOUQyOTg2Mzk0NDgwMENDQTkxODI5RTQ0NDc0OThBMjBDRDlDMzk3M0E2QjU5MzQ2Qzc1QUI5NSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTFDUnFvNjZkS1lZNVJJQU15cEdDbmtSSFNZb2d6Wnc1YzZhMWswYkhXcmxYTWhBa20xbHowYzhRWFdmSjliMXZCNzJkTGFidzh3WUlkOE10bnBzSEhCRUM4cGRrWXdSQUlnUWxiNkhKNTNoc1RBZlZpZCtBT2RCVnZNRjdyYWhJS05MQkhVZ241MnpCRUNJR0xVcUZ1OGExQUFIUkpjVm9uS1lFbm1oSndiQ1hMbitqZTduYTFXRDEvb2NCSkFFNHZmdnJHU21aQzJ1QVVHbU01ZElCdG9TZ0VVZXkrMlZsZURZRXNjZTk0dHhZY2pSOFo3UUxOYWxpRDh3L2JENS9odllROG1lVjFXZzFqSkZOZTBDQT09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDJDMTQ2OEI0QTExRDI4MUY5M0VGMzM3Qzk1RTRBMDhERjAwMDBGREVGQjZEMEVBOUJDMDVGQkQ1RDYxQTFGNUEiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUwc0ZHaTBvUjBvSDVQdk0zeVY1S0NOOEFBUDN2dHREcW04QmZ2VjFob2ZXbk1oQWtNVW1DRDJhUG1nRkREUm1pbXZTaWNTSVNjdzZZTnI0MkR3NFJBZHdyT0Fka2N3UlFJaEFKRk9ITWc2cVRHOHY2MGRocmVuWVlrNmN3T2FSWHEwUk5tTGp5eUNpejVsQWlBZFUwWWtEVUpRaG5OOFJ5OHMrNnpUSkxpTkxidE04b08vY0xudXJWcFJNM0FTUUdBTGFySEFzSmtTWlF0R2RNMkFhUi9qb0ZLL2poRFU1NytsK1JTWWpyaS95ZEUyMERhS2Fud2tNRW9WbEJUZzdsWDRoWWpFbm1rcW83M3dJdGhMT0FRPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURBNTRDODVGOTEyMTlGRDI1OTEzNEI2QjEyNkFENjRBRTcyMDRCODFERDQwNTI1MTA2NTdFMUE1Njk3MjQ2QUQyIiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMmxUSVg1RWhuOUpaRTB0ckVtcldTdWNnUzRIZFFGSlJCbGZocFdseVJxMG5NaEFsOGNKZXJQdit2bzFCSzYxMXhWVHBHeGpqci9DdXhQVGdVOFVSTTRlVFo1ZGtZd1JBSWdkSzNjUVYyWS92aVpuZS9QYm9LU0tld25nVHVJTjJNNmM4YXp3cWMyMHVVQ0lBYzZHb05UK1AyWUJ5NDlnZGF1NFA3eVN3V29RWDVuZjlkUXhpUWF2NXdJY0JKQXFpQ0swZDZRUlpTcGlWSHA4TzlubEtYQ1NFaHNpU05jV2NFRm0vZkdoSkFuQU4wT3Y5SElOSWQxcHhyQm4yZEtSZWdMVHZZRzNCcGJ6Ly9ITGdFZERBPT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVEOUFFNEY1ODg3QkEwMjlFQjdDMDg4NDQ4NkQyM0NGMjgxOTc1Rjc3M0Y0NEJEMjEzMDU0MjE5ODgyQzQxMUNDNyIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTJhNVBXSWU2QXA2M3dJaEVodEk4OG9HWFgzYy9STDBoTUZRaG1JTEVFY3gzTWhBbUcyemd2OEZCWnNaSlU4YVBhcHdvOWNJcVF2NC9NU1Mxb1ZBNWVWTWl3TGRrWXdSQUlnRitMT2U0ZVkwZ3A5dHRxaDJnbnYrejc1T3FMeU9RTXBHUEFMZ20rTnRPc0NJQ0RYQlpWUHRwcm1CRGtCSmtQRlNuRTU1RDllS1lSSDh6L2lZMUV0cE5wbGNCSkFBREVXR1ZUODBPd2hkMWxoMkpzVS9vWmxtZU5GNVdON1l2bEI4bGxFeGFSS0VWQytHVzlXZytpTklRM3JtVjdQOGFOYVZ1YWFiRzAwZk9na2d6TmhEdz09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFREE4RDI5RjQwQ0VCMjg5OTU2MTc2NDFBM0JDNDI2OTJFMURFODgzMjE0RjYxMkZCQjYyMDg3QTE0OEU1RjZGOUEiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUybzBwOUF6cktKbFdGMlFhTzhRbWt1SGVpRElVOWhMN3RpQ0hvVWpsOXZtbk1oQW5ZblA3RWc2VmdObkVVVFJFMjlkNjRqUVQvaUJjV1RRdE5yVXp5RDZNSitka2N3UlFJaEFPRXNWNWFuVGtsb1NtVFpSYmltTXlCS3FIb0pZWGNCQmU4bExpUFlDN21VQWlBejJhTk9wZlEvMUx5Y1dsb0lNdmRoeHppbnE1WDdVYXMvdU9TYjl3aDhkM0FTUUxWa2ZwVy9HTzZ3ZFQ2QXV1U0o1NlR0TTM0M3BETkgraVN6eGx0SWZkclBpVXhUNXJmNGsyMWxRUXVQQ2xYbTkrU2ZLckNpVVhaSzdkajAvR1dUWVFnPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQzOEIwMjg4RUEyNDBCNENERUMxOEExQTYyODlFQjQ5MDA3RTRFQkMwREU5NDQ4MDNFQjdFRjE0MUM1NjY0MDczIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMDRzQ2lPb2tDMHpld1lvYVlvbnJTUUIrVHJ3TjZVU0FQcmZ2RkJ4V1pBYzNNaEFnT0tjdkl1Y2hhbHJady9nbFR1T3hWM0lPQ2Nwb3J4TUI3SnFBVnVwazFlZGtjd1JRSWhBT3ZSenBlK0lZWksxTXlJbklRWjg3SnZQMko4U0lYQ1haTVBCQ2RJVEJhbUFpQVNhdkpYaTlwd3M4ckRESlN4aEdNbG1FN3pJNWJTQThpdnRSQzlMZ3ErVVhBU1FEbDNlb3FMSUQrRVRKTk0remJNdXZ3dmNIRUl4ZUJaa1o5ZnA1akp2Nk9DVFB3bGo0VEpTdXkxYXZFV3FVWVMycml2NUR2bDJoYUZVb0NIZjR5YXdBQT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVERUUxMERDMzZBQ0Q5OTVDOEUwRTg2RTNDRDJGQkY4MzAxQTRBQzJCODg0N0I2MUExOTM1REU0OTczQjQwN0MwRSIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTN1RU53MnJObVZ5T0RvYmp6UysvZ3dHa3JDdUlSN1lhR1RYZVNYTzBCOERuTWhBbVgwdmI3aitsZ0JqRmpiTjlSbEE4Nko3QU8yVm42SExxdU8zYWlzSzRtd2RrWXdSQUlnZnhCTG43aTRqZy9kaTBVMjVxNmtJYlZmVHpxYkEwU0NwUTBJNTdUT0ZrY0NJRk10SlFwRU5qQjJLMkVtdkJIUHZOY3d1U1BjM3ZzRWVxRTJyTkovY1Q1RGNCSkFmNjhYUEZ1NVJqQ2VMZ3BGSk03UEtGTGdvVjhlMW54TzVld2pxOVErVEFFR25GeVMwSU93ZjZwT090SVZNZFZlWHUxdjZwNGZoWFFrZGloSHQxeDZBZz09In0seyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDU4M0VDRDA2QzNCNzM2OTk4MEU2NUM3OEM0NDBBNTI5MzAwRjU1N0VEODEyNTYyODNGN0RENUFBMzUxM0EzMzQiLCJtYW5pZmVzdCI6IkpBQUFBQUZ4SWUxWVBzMEd3N2MybVlEbVhIakVRS1VwTUE5VmZ0Z1NWaWcvZmRXcU5ST2pOSE1oQXl1VW56WloxbjIvR2FUbUUxbTdIL3Y5WWxaeURFd0hZM2dTSFVBM0lDTDlka1l3UkFJZ0h4MlBIdmlkb04rNXlHOVdlQVMyazdud0lNOGFqeFFXNndqdnQ4a0JlbkFDSUROeFFQUWtEeURKSDlzZVM1QzYybUFhclFtZ2lOODlZUzNqaE50bnZFSXFjQkpBajdKaDBLYWMrYUpkcG9lcHUvK2VKS25uRlE3WUJ5WkI4ZU1aK1NTMXpMaEUrbGlwLzQ5cXFWTmNwQXhFcWZhR3R4SnpvREREMS9RYnVVN05PU1BrQ2c9PSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQ5NUM1MTcyQjJBRDdEMzk0MzRFRUJDNDM2QjY1QjNCQjdFNThENUMxQ0VGQzgyMEI2OTcyQUNBRDc3NkUyODZBIiwibWFuaWZlc3QiOiJKQUFBQUFGeEllMlZ4UmNyS3RmVGxEVHV2RU5yWmJPN2ZsalZ3Yzc4Z2d0cGNxeXRkMjRvYW5NaEFpcWNSZGUzTVFaMDc1ZmE0Wk5OeVJhWUpHTWRCTmtCbm4zYlFyS3NlQkRRZGtZd1JBSWdVK0xmY0U3MURQVnJPK0t0VUJqUTlEMnUway9QcjdsdWtPMW5QUmo2aFNBQ0lETkxZQy9KRmdvYkNzSWEwQkd3KzZiVW5PdzltZVUzRmRYZ1I3UTdTb3FKY0JKQVhRYWtPb1FuUHAzcGNMTDd6ZEtDUFVYNGIrL0ZDOVVuaHFwK085eFFGblJhQ1dWR21rNU1KT0lNczRXT1FkcE0xajNPZ1NzQUJtUnVDWFl2d28vbkR3PT0ifSx7InZhbGlkYXRpb25fcHVibGljX2tleSI6IkVEOTAxNjNEMkJGMEI3Nzg4OTA0QzRBNDExOEQ3RDk2ODkyMEU4NDdEODhCNzkxNzgzOTA4MzdERTNDQTI2MTU2MiIsIm1hbmlmZXN0IjoiSkFBQUFBRnhJZTJRRmowcjhMZDRpUVRFcEJHTmZaYUpJT2hIMkl0NUY0T1FnMzNqeWlZVlluTWhBNzJWVFJpR2hrSkJ0cWdHSER6SGo3WWJDNitOc0VLckZITnVFL0xPM1RuNWRrWXdSQUlnZjhzK2ZZdDBsbHJLUTJxaVdQbkdtYjZxSlBvZThPbkNNM1ZTMjlYS2JZWUNJSEdubEo0T1RzMmRYdWdPNkJ0bzYzTnBEdnZxSitXSXdkWUtxWjZCaUJmemNCSkFHdk50a29nNHBmRTVkWlJ3bWljODdaQmVldW5PaDRZcEwwU0VSZHhXajQzQ3M5ODE1ekZKdVp5c1NhVVgyUi92ZEUyVktxdlNncXF0REVuck1vMm9Bdz09In1dfQ==",
50  "signature" : "9FF30EDC4DED7ABCD0D36389B7C716EED4B5E4F043902853534EBAC7BE966BB3813D5CF25E4DADA5E657CCF019FFD11847FD3CC44B5559A6FCEEE4C3DCFF8D0E",
51  "version": 1
52 }
53 )vl";
54 }
55 
56 auto constexpr default_expires = std::chrono::seconds{3600};
58 } // namespace detail
59 
60 class ValidatorSite_test : public beast::unit_test::suite
61 {
62 private:
64 
65  void
67  {
68  testcase("Config Load");
69 
70  using namespace jtx;
71 
72  Env env(*this);
73  auto trustedSites =
74  std::make_unique<ValidatorSite>(env.app(), env.journal);
75 
76  // load should accept empty sites list
77  std::vector<std::string> emptyCfgSites;
78  BEAST_EXPECT(trustedSites->load(emptyCfgSites));
79 
80  // load should accept valid validator site uris
81  std::vector<std::string> cfgSites({
82  "http://ripple.com/", "http://ripple.com/validators",
83  "http://ripple.com:8080/validators",
84  "http://207.261.33.37/validators",
85  "http://207.261.33.37:8080/validators",
86  "https://ripple.com/validators",
87  "https://ripple.com:443/validators",
88  "file:///etc/opt/ripple/validators.txt",
89  "file:///C:/Lib/validators.txt"
90 #if !_MSC_VER
91  ,
92  "file:///"
93 #endif
94  });
95  BEAST_EXPECT(trustedSites->load(cfgSites));
96 
97  // load should reject validator site uris with invalid schemes
98  std::vector<std::string> badSites({"ftp://ripple.com/validators"});
99  BEAST_EXPECT(!trustedSites->load(badSites));
100 
101  badSites[0] = "wss://ripple.com/validators";
102  BEAST_EXPECT(!trustedSites->load(badSites));
103 
104  badSites[0] = "ripple.com/validators";
105  BEAST_EXPECT(!trustedSites->load(badSites));
106 
107  // Host names are not supported for file URLs
108  badSites[0] = "file://ripple.com/vl.txt";
109  BEAST_EXPECT(!trustedSites->load(badSites));
110 
111  // Even local host names are not supported for file URLs
112  badSites[0] = "file://localhost/home/user/vl.txt";
113  BEAST_EXPECT(!trustedSites->load(badSites));
114 
115  // Nor IP addresses
116  badSites[0] = "file://127.0.0.1/home/user/vl.txt";
117  BEAST_EXPECT(!trustedSites->load(badSites));
118 
119  // File URL path can not be empty
120  badSites[0] = "file://";
121  BEAST_EXPECT(!trustedSites->load(badSites));
122 
123 #if _MSC_VER // Windows paths strip off the leading /, leaving the path empty
124  // File URL path can not be a directory
125  // (/ is the only path we can reasonably assume is a directory)
126  badSites[0] = "file:///";
127  BEAST_EXPECT(!trustedSites->load(badSites));
128 #endif
129  }
130 
132  {
135  bool ssl;
136  bool failFetch = false;
137  bool failApply = false;
138  int serverVersion = 1;
143  };
144  void
146  {
147  testcase << "Fetch list - "
148  << boost::algorithm::join(
149  paths |
150  boost::adaptors::transformed(
151  [](FetchListConfig const& cfg) {
152  return cfg.path +
153  (cfg.ssl ? " [https] v" : " [http] v") +
155  " " + cfg.msg;
156  }),
157  ", ");
158  using namespace jtx;
159  using namespace std::chrono_literals;
160 
161  Env env(*this);
162  auto& trustedKeys = env.app().validators();
163  env.timeKeeper().set(env.timeKeeper().now() + 30s);
164 
165  test::StreamSink sink;
166  beast::Journal journal{sink};
167 
168  PublicKey emptyLocalKey;
169  std::vector<std::string> emptyCfgKeys;
170  struct publisher
171  {
172  publisher(FetchListConfig const& c) : cfg{c}
173  {
174  }
177  std::string uri;
178  FetchListConfig const& cfg;
179  bool isRetry;
180  };
181  std::vector<publisher> servers;
182 
183  auto constexpr listSize = 20;
184  std::vector<std::string> cfgPublishers;
185 
186  for (auto const& cfg : paths)
187  {
188  servers.push_back(cfg);
189  auto& item = servers.back();
190  item.isRetry = cfg.path == "/bad-resource";
191  item.list.reserve(listSize);
192  while (item.list.size() < listSize)
193  item.list.push_back(TrustedPublisherServer::randomValidator());
194 
195  NetClock::time_point const expires =
196  env.timeKeeper().now() + cfg.expiresFromNow;
197  NetClock::time_point const effective2 =
198  expires - cfg.effectiveOverlap;
199  NetClock::time_point const expires2 =
200  effective2 + cfg.expiresFromNow;
201  item.server = make_TrustedPublisherServer(
202  env.app().getIOService(),
203  item.list,
204  expires,
205  {{effective2, expires2}},
206  cfg.ssl,
207  cfg.serverVersion);
208  cfgPublishers.push_back(strHex(item.server->publisherPublic()));
209 
210  std::stringstream uri;
211  uri << (cfg.ssl ? "https://" : "http://")
212  << item.server->local_endpoint() << cfg.path;
213  item.uri = uri.str();
214  }
215 
216  BEAST_EXPECT(
217  trustedKeys.load(emptyLocalKey, emptyCfgKeys, cfgPublishers));
218 
219  // Normally, tests will only need a fraction of this time,
220  // but sometimes DNS resolution takes an inordinate amount
221  // of time, so the test will just wait.
222  auto sites = std::make_unique<ValidatorSite>(env.app(), journal, 12s);
223 
225  for (auto const& u : servers)
226  uris.push_back(u.uri);
227  sites->load(uris);
228  sites->start();
229  sites->join();
230 
231  auto const jv = sites->getJson();
232  for (auto const& u : servers)
233  {
234  for (auto const& val : u.list)
235  {
236  BEAST_EXPECT(
237  trustedKeys.listed(val.masterPublic) != u.cfg.failApply);
238  BEAST_EXPECT(
239  trustedKeys.listed(val.signingPublic) != u.cfg.failApply);
240  }
241 
242  Json::Value myStatus;
243  for (auto const& vs : jv[jss::validator_sites])
244  if (vs[jss::uri].asString().find(u.uri) != std::string::npos)
245  myStatus = vs;
246  BEAST_EXPECTS(
247  myStatus[jss::last_refresh_message].asString().empty() !=
248  u.cfg.failFetch,
249  to_string(myStatus) + "\n" + sink.messages().str());
250 
251  if (!u.cfg.msg.empty())
252  {
253  BEAST_EXPECTS(
254  sink.messages().str().find(u.cfg.msg) != std::string::npos,
255  sink.messages().str());
256  }
257 
258  if (u.cfg.expectedRefreshMin)
259  {
260  BEAST_EXPECTS(
261  myStatus[jss::refresh_interval_min].asInt() ==
262  u.cfg.expectedRefreshMin,
263  to_string(myStatus));
264  }
265 
266  if (u.cfg.failFetch)
267  {
268  using namespace std::chrono;
269  log << " -- Msg: "
270  << myStatus[jss::last_refresh_message].asString()
271  << std::endl;
272  std::stringstream nextRefreshStr{
273  myStatus[jss::next_refresh_time].asString()};
274  system_clock::time_point nextRefresh;
275  date::from_stream(nextRefreshStr, "%Y-%b-%d %T", nextRefresh);
276  BEAST_EXPECT(!nextRefreshStr.fail());
277  auto now = system_clock::now();
278  BEAST_EXPECTS(
279  nextRefresh <= now + (u.isRetry ? seconds{30} : minutes{5}),
280  "Now: " + to_string(now) + ", NR: " + nextRefreshStr.str());
281  }
282  }
283  }
284 
285  void
287  {
288  testcase << "File list - " << paths[0].first
289  << (paths.size() > 1 ? ", " + paths[1].first : "");
290 
291  using namespace jtx;
292 
293  Env env(*this);
294 
295  test::StreamSink sink;
296  beast::Journal journal{sink};
297 
298  struct publisher
299  {
300  std::string uri;
301  std::string expectMsg;
302  bool shouldFail;
303  };
304  std::vector<publisher> servers;
305 
306  for (auto const& cfg : paths)
307  {
308  servers.push_back({});
309  auto& item = servers.back();
310  item.shouldFail = !cfg.second.empty();
311  item.expectMsg = cfg.second;
312 
313  std::stringstream uri;
314  uri << "file://" << cfg.first;
315  item.uri = uri.str();
316  }
317 
318  auto sites = std::make_unique<ValidatorSite>(env.app(), journal);
319 
321  for (auto const& u : servers)
322  uris.push_back(u.uri);
323  sites->load(uris);
324  sites->start();
325  sites->join();
326 
327  for (auto const& u : servers)
328  {
329  auto const jv = sites->getJson();
330  Json::Value myStatus;
331  for (auto const& vs : jv[jss::validator_sites])
332  if (vs[jss::uri].asString().find(u.uri) != std::string::npos)
333  myStatus = vs;
334  BEAST_EXPECTS(
335  myStatus[jss::last_refresh_message].asString().empty() !=
336  u.shouldFail,
337  to_string(myStatus));
338  if (u.shouldFail)
339  {
340  BEAST_EXPECTS(
341  sink.messages().str().find(u.expectMsg) !=
342  std::string::npos,
343  sink.messages().str());
344  log << " -- Msg: "
345  << myStatus[jss::last_refresh_message].asString()
346  << std::endl;
347  }
348  }
349  }
350 
351  void
353  {
354  auto fullPath = [](detail::FileDirGuard const& guard) {
355  auto absPath = absolute(guard.file()).string();
356  if (absPath.front() != '/')
357  absPath.insert(absPath.begin(), '/');
358  return absPath;
359  };
360  {
361  // Create a file with a real validator list
363  *this, "test_val", "vl.txt", detail::realValidatorContents());
364  // Create a file with arbitrary content
365  detail::FileDirGuard hello(
366  *this, "test_val", "helloworld.txt", "Hello, world!");
367  // Create a file with malformed Json
369  *this,
370  "test_val",
371  "json.txt",
372  R"json({ "version": 2, "extra" : "value" })json");
373  auto const goodPath = fullPath(good);
374  auto const helloPath = fullPath(hello);
375  auto const jsonPath = fullPath(json);
376  auto const missingPath = jsonPath + ".bad";
377  testFileList({
378  {goodPath, ""},
379  {helloPath,
380  "Unable to parse JSON response from file://" + helloPath},
381  {jsonPath,
382  "Missing fields in JSON response from file://" + jsonPath},
383  {missingPath, "Problem retrieving from file://" + missingPath},
384  });
385  }
386  }
387 
388 public:
389  void
390  run() override
391  {
392  testConfigLoad();
393 
394  for (auto ssl : {true, false})
395  {
396  // fetch single site
397  testFetchList({{"/validators", "", ssl}});
398  testFetchList({{"/validators2", "", ssl}});
399  // fetch multiple sites
400  testFetchList({{"/validators", "", ssl}, {"/validators", "", ssl}});
402  {{"/validators", "", ssl}, {"/validators2", "", ssl}});
404  {{"/validators2", "", ssl}, {"/validators", "", ssl}});
406  {{"/validators2", "", ssl}, {"/validators2", "", ssl}});
407  // fetch single site with single redirects
408  testFetchList({{"/redirect_once/301", "", ssl}});
409  testFetchList({{"/redirect_once/302", "", ssl}});
410  testFetchList({{"/redirect_once/307", "", ssl}});
411  testFetchList({{"/redirect_once/308", "", ssl}});
412  // one redirect, one not
414  {{"/validators", "", ssl}, {"/redirect_once/302", "", ssl}});
416  {{"/validators2", "", ssl}, {"/redirect_once/302", "", ssl}});
417  // UNLs with a "gap" between validUntil of one and validFrom of the
418  // next
420  {{"/validators2",
421  "",
422  ssl,
423  false,
424  false,
425  1,
427  std::chrono::seconds{-90}}});
428  // fetch single site with undending redirect (fails to load)
430  {{"/redirect_forever/301",
431  "Exceeded max redirects",
432  ssl,
433  true,
434  true}});
435  // two that redirect forever
437  {{"/redirect_forever/307",
438  "Exceeded max redirects",
439  ssl,
440  true,
441  true},
442  {"/redirect_forever/308",
443  "Exceeded max redirects",
444  ssl,
445  true,
446  true}});
447  // one undending redirect, one not
449  {{"/validators", "", ssl},
450  {"/redirect_forever/302",
451  "Exceeded max redirects",
452  ssl,
453  true,
454  true}});
455  // one undending redirect, one not
457  {{"/validators2", "", ssl},
458  {"/redirect_forever/302",
459  "Exceeded max redirects",
460  ssl,
461  true,
462  true}});
463  // invalid redir Location
465  {{"/redirect_to/ftp://invalid-url/302",
466  "Invalid redirect location",
467  ssl,
468  true,
469  true}});
471  {{"/redirect_to/file://invalid-url/302",
472  "Invalid redirect location",
473  ssl,
474  true,
475  true}});
476  // invalid json
478  {{"/validators/bad",
479  "Unable to parse JSON response",
480  ssl,
481  true,
482  true}});
484  {{"/validators2/bad",
485  "Unable to parse JSON response",
486  ssl,
487  true,
488  true}});
489  // error status returned
491  {{"/bad-resource", "returned bad status", ssl, true, true}});
492  // location field missing
494  {{"/redirect_nolo/308",
495  "returned a redirect with no Location",
496  ssl,
497  true,
498  true}});
499  // json fields missing
501  {{"/validators/missing",
502  "Missing fields in JSON response",
503  ssl,
504  true,
505  true}});
507  {{"/validators2/missing",
508  "Missing fields in JSON response",
509  ssl,
510  true,
511  true}});
512  // timeout
513  testFetchList({{"/sleep/13", "took too long", ssl, true, true}});
514  // bad manifest format using known versions
515  // * Retrieves a v1 formatted list claiming version 2
517  {{"/validators", "Missing fields", ssl, true, true, 2}});
518  // * Retrieves a v2 formatted list claiming version 1
520  {{"/validators2", "Missing fields", ssl, true, true, 0}});
521  // bad manifest version
522  // Because versions other than 1 are treated as v2, the v1
523  // list won't have the blobs_v2 fields, and thus will claim to have
524  // missing fields
526  {{"/validators", "Missing fields", ssl, true, true, 4}});
528  {{"/validators2",
529  "1 unsupported version",
530  ssl,
531  false,
532  true,
533  4}});
534  using namespace std::chrono_literals;
535  // get expired validator list
537  {{"/validators",
538  "Applied 1 expired validator list(s)",
539  ssl,
540  false,
541  false,
542  1,
543  0s}});
545  {{"/validators2",
546  "Applied 1 expired validator list(s)",
547  ssl,
548  false,
549  false,
550  1,
551  0s,
552  -1s}});
553  // force an out-of-range validUntil value
555  {{"/validators",
556  "1 invalid validator list(s)",
557  ssl,
558  false,
559  true,
560  1,
562  // force an out-of-range validUntil value on the future list
563  // The first list is accepted. The second fails. The parser
564  // returns the "best" result, so this looks like a success.
566  {{"/validators2",
567  "",
568  ssl,
569  false,
570  false,
571  1,
573  299s}});
574  // force an out-of-range validFrom value
575  // The first list is accepted. The second fails. The parser
576  // returns the "best" result, so this looks like a success.
578  {{"/validators2",
579  "",
580  ssl,
581  false,
582  false,
583  1,
585  301s}});
586  // force an out-of-range validUntil value on _both_ lists
588  {{"/validators2",
589  "2 invalid validator list(s)",
590  ssl,
591  false,
592  true,
593  1,
596  // verify refresh intervals are properly clamped
598  {{"/validators/refresh/0",
599  "",
600  ssl,
601  false,
602  false,
603  1,
606  1}}); // minimum of 1 minute
608  {{"/validators2/refresh/0",
609  "",
610  ssl,
611  false,
612  false,
613  1,
616  1}}); // minimum of 1 minute
618  {{"/validators/refresh/10",
619  "",
620  ssl,
621  false,
622  false,
623  1,
626  10}}); // 10 minutes is fine
628  {{"/validators2/refresh/10",
629  "",
630  ssl,
631  false,
632  false,
633  1,
636  10}}); // 10 minutes is fine
638  {{"/validators/refresh/2000",
639  "",
640  ssl,
641  false,
642  false,
643  1,
646  60 * 24}}); // max of 24 hours
648  {{"/validators2/refresh/2000",
649  "",
650  ssl,
651  false,
652  false,
653  1,
656  60 * 24}}); // max of 24 hours
657  }
658  testFileURLs();
659  }
660 };
661 
663 
664 } // namespace test
665 } // 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:66
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:135
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:352
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:142
ripple::test::detail::default_effective_overlap
constexpr auto default_effective_overlap
Definition: ValidatorSite_test.cpp:57
ripple::test::detail::realValidatorContents
constexpr const char * realValidatorContents()
Definition: ValidatorSite_test.cpp:44
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:145
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:286
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:138
std::to_string
T to_string(T... args)
ripple::test::ValidatorSite_test::FetchListConfig::path
std::string path
Definition: ValidatorSite_test.cpp:133
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:136
ripple::test::detail::default_expires
constexpr auto default_expires
Definition: ValidatorSite_test.cpp:56
ripple::test::ValidatorSite_test::FetchListConfig::effectiveOverlap
std::chrono::seconds effectiveOverlap
Definition: ValidatorSite_test.cpp:140
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:60
ripple::test::ValidatorSite_test::FetchListConfig
Definition: ValidatorSite_test.cpp:131
ripple::test::ValidatorSite_test::FetchListConfig::expiresFromNow
std::chrono::seconds expiresFromNow
Definition: ValidatorSite_test.cpp:139
ripple::test::ValidatorSite_test::run
void run() override
Definition: ValidatorSite_test.cpp:390
ripple::test::ValidatorSite_test::FetchListConfig::failApply
bool failApply
Definition: ValidatorSite_test.cpp:137
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:40
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:134
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)