3#include <xrpld/app/main/DBInit.h> 
    4#include <xrpld/app/misc/Manifest.h> 
    5#include <xrpld/app/misc/ValidatorList.h> 
    6#include <xrpld/app/rdb/Wallet.h> 
    8#include <xrpl/basics/base64.h> 
    9#include <xrpl/basics/contract.h> 
   10#include <xrpl/protocol/STExchange.h> 
   11#include <xrpl/protocol/SecretKey.h> 
   12#include <xrpl/protocol/Sign.h> 
   14#include <boost/algorithm/string.hpp> 
   15#include <boost/filesystem.hpp> 
   16#include <boost/utility/in_place_factory.hpp> 
   39        using namespace boost::filesystem;
 
   40        if (!exists(dbPath) || !is_directory(dbPath) || !is_empty(dbPath))
 
 
   48        using namespace boost::filesystem;
 
   51            create_directory(dbPath);
 
   55        if (!is_directory(dbPath))
 
   58            Throw<std::runtime_error>(
 
   59                "Cannot create directory: " + dbPath.string());
 
 
   62    static boost::filesystem::path
 
   65        return boost::filesystem::current_path() / 
"manifest_test_databases";
 
 
  100        st[sfPublicKey] = pk;
 
  101        st[sfSigningPubKey] = spk;
 
 
  122        bool invalidSig = 
false)
 
  128        st[sfPublicKey] = pk;
 
 
  154        st[sfPublicKey] = pk;
 
  172            return std::move(*r);
 
  173        Throw<std::runtime_error>(
"Could not create a revocation manifest");
 
 
  185        bool invalidSig = 
false)
 
  191        st[sfSequence] = 
seq;
 
  192        st[sfPublicKey] = pk;
 
  193        st[sfSigningPubKey] = spk;
 
  212            static_cast<char const*
>(s.
data()),
 
  215            return std::move(*r);
 
  216        Throw<std::runtime_error>(
"Could not create a manifest");
 
 
  243            auto getPopulatedManifests =
 
  247                cache.for_each_manifest(
 
  257                        return lhs->serialized < rhs->serialized;
 
  262                sort(getPopulatedManifests(m)));
 
  264            auto& app = env.
app();
 
  269                app.config().legacy(
"database_path"),
 
  277                    "ValidatorManifests",
 
  279                        return unl->listed(pubKey);
 
  284                loaded.
load(*dbCon, 
"ValidatorManifests");
 
  288                    sort(getPopulatedManifests(loaded)));
 
  290                for (
auto const& man : loadedManifests)
 
  291                    BEAST_EXPECT(man->revoked());
 
  298                for (
auto const& man : inManifests)
 
  301                unl->load({}, s1, keys);
 
  305                    "ValidatorManifests",
 
  307                        return unl->listed(pubKey);
 
  310                loaded.
load(*dbCon, 
"ValidatorManifests");
 
  314                    sort(getPopulatedManifests(loaded)));
 
  316                if (inManifests.
size() == loadedManifests.
size())
 
  321                        loadedManifests.
begin(),
 
  337                BEAST_EXPECT(!loaded.
load(
 
  339                    "ValidatorManifests",
 
  350                BEAST_EXPECT(loaded.
load(
 
  352                    "ValidatorManifests",
 
  363                BEAST_EXPECT(!loaded.
load(
 
  365                    "ValidatorManifests",
 
  376                BEAST_EXPECT(!loaded.
load(
 
  378                    "ValidatorManifests",
 
  381                BEAST_EXPECT(!loaded.
revoked(pk));
 
  385                BEAST_EXPECT(!loaded.
load(
 
  387                    "ValidatorManifests",
 
  390                BEAST_EXPECT(!loaded.
revoked(pk));
 
  394                BEAST_EXPECT(loaded.
load(
 
  396                    "ValidatorManifests",
 
  400                BEAST_EXPECT(loaded.
revoked(pk));
 
  403        boost::filesystem::remove(
 
 
  419        st[sfPublicKey] = pk;
 
  420        st[sfSigningPubKey] = kp.first;
 
  428        BEAST_EXPECT(
strHex(masterSig) == 
strHex(m.getMasterSignature()));
 
 
  466        BEAST_EXPECT(cache.
getMasterKey(kp0.first) == kp0.first);
 
  476        BEAST_EXPECT(cache.
getMasterKey(kp0.first) == kp0.first);
 
  484        BEAST_EXPECT(cache.
revoked(pk));
 
  486        BEAST_EXPECT(cache.
getMasterKey(kp0.first) == kp0.first);
 
  487        BEAST_EXPECT(cache.
getMasterKey(kp1.first) == kp1.first);
 
 
  496            auto const valSecret = parseBase58<SecretKey>(
 
  498                "paQmjZ37pKKPMrgadBLsuf9ab7Y7EUNzh27LQrZqoexpAs31nJi");
 
  503                "eyJ2YWxpZGF0aW9uX3NlY3JldF9rZXkiOiI5ZWQ0NWY4NjYyNDFjYzE4YTI3ND" 
  505                " \tQzODdjMDYyNTkwNzk3MmY0ZTcxOTAyMzFmYWE5Mzc0NTdmYTlkYWY2Iiwib" 
  507                "\tc3QiOiJKQUFBQUFGeEllMUZ0d21pbXZHdEgyaUNjTUpxQzlnVkZLaWxHZncx" 
  510                "hYWExwbGMyR25NaEFrRTFhZ3FYeEJ3RHdEYklENk9NU1l1TTBGREFscEFnTms4" 
  512                "bjdNTzJmZGtjd1JRSWhBT25ndTlzQUtxWFlvdUorbDJWMFcrc0FPa1ZCK1pSUz" 
  514                "hsSkFmVXNYZkFpQnNWSkdlc2FhZE9KYy9hQVpva1MxdnltR21WcmxIUEtXWDNZ" 
  516                "NmluOEhBU1FLUHVnQkQ2N2tNYVJGR3ZtcEFUSGxHS0pkdkRGbFdQWXk1QXFEZW" 
  518                "VUSmEydzBpMjFlcTNNWXl3TFZKWm5GT3I3QzBrdzJBaVR6U0NqSXpkaXRROD0i" 
  522                "JAAAAAFxIe1FtwmimvGtH2iCcMJqC9gVFKilGfw1/" 
  523                "vCxHXXLplc2GnMhAkE1agqXxBwD" 
  524                "wDbID6OMSYuM0FDAlpAgNk8SKFn7MO2fdkcwRQIhAOngu9sAKqXYouJ+l2V0W+" 
  526                "+ZRS6PShlJAfUsXfAiBsVJGesaadOJc/" 
  527                "aAZokS1vymGmVrlHPKWX3Yywu6in8HASQKPu" 
  528                "gBD67kMaRFGvmpATHlGKJdvDFlWPYy5AqDedFv5TJa2w0i21eq3MYywLVJZnFO" 
  534            BEAST_EXPECT(token->validationSecret == *valSecret);
 
  535            BEAST_EXPECT(token->manifest == 
manifest);
 
 
  557            st[sfPublicKey] = pk;
 
  558            st[sfSigningPubKey] = spk;
 
  561                st[sfVersion] = version;
 
 
  595            0x99, 0x30, 0xE7, 0xFC, 0x9D, 0x56, 0xBB, 0x25, 0xD6, 0x89, 0x3B,
 
  596            0xA3, 0xF3, 0x17, 0xAE, 0x5B, 0xCF, 0x33, 0xB3, 0x29, 0x1B, 0xD6,
 
  597            0x3D, 0xB3, 0x26, 0x54, 0xA3, 0x13, 0x22, 0x2F, 0x7F, 0xD0, 0x20};
 
  618        auto toString = [](
STObject const& st) {
 
  625        for (
auto const keyType : keyTypes)
 
  630            for (
auto const sKeyType : keyTypes)
 
  635                auto buildManifestObject =
 
  638                        bool noSigningPublic = 
false,
 
  639                        bool noSignature = 
false) {
 
  641                        st[sfSequence] = 
seq;
 
  642                        st[sfPublicKey] = pk;
 
  647                        if (!noSigningPublic)
 
  648                            st[sfSigningPubKey] = spk;
 
  664                    testcase << 
"deserializeManifest: normal manifest (" 
  672                        auto const m = toString(st);
 
  676                        BEAST_EXPECT(
manifest->masterKey == pk);
 
  677                        BEAST_EXPECT(
manifest->signingKey == spk);
 
  678                        BEAST_EXPECT(
manifest->sequence == sequence);
 
  679                        BEAST_EXPECT(
manifest->serialized == m);
 
  680                        BEAST_EXPECT(
manifest->domain.empty());
 
  693                            buildManifestObject(++sequence, 
std::string{
"a.b"});
 
  699                            buildManifestObject(++sequence, s + 
".example.com");
 
  705                            buildManifestObject(++sequence, s + 
".example.com");
 
  709                    auto const st = buildManifestObject(
 
  714                        auto const m = toString(st);
 
  718                        BEAST_EXPECT(
manifest->masterKey == pk);
 
  719                        BEAST_EXPECT(
manifest->signingKey == spk);
 
  720                        BEAST_EXPECT(
manifest->sequence == sequence);
 
  721                        BEAST_EXPECT(
manifest->serialized == m);
 
  722                        BEAST_EXPECT(
manifest->domain == 
"example.com");
 
  728                        badSigSt[sfSequence] = sequence + 1;
 
  730                        auto const m = toString(badSigSt);
 
  734                        BEAST_EXPECT(
manifest->masterKey == pk);
 
  735                        BEAST_EXPECT(
manifest->signingKey == spk);
 
  736                        BEAST_EXPECT(
manifest->sequence == sequence + 1);
 
  737                        BEAST_EXPECT(
manifest->serialized == m);
 
  738                        BEAST_EXPECT(
manifest->domain == 
"example.com");
 
  744                        BEAST_EXPECT(badSt.delField(sfSequence));
 
  750                        BEAST_EXPECT(badSt.delField(sfPublicKey));
 
  762                        badSt[sfPublicKey] = 
makeSlice(shortKey);
 
  768                        BEAST_EXPECT(badSt.delField(sfSigningPubKey));
 
  774                        badSt[sfSigningPubKey] = 
makeSlice(badKey);
 
  780                        badSt[sfSigningPubKey] = 
makeSlice(shortKey);
 
  786                        BEAST_EXPECT(badSt.delField(sfMasterSignature));
 
  792                        BEAST_EXPECT(badSt.delField(sfSignature));
 
  798                        st[sfSequence] = 314159;
 
  799                        st[sfPublicKey] = pk;
 
  800                        st[sfSigningPubKey] = pk;
 
  816                    testcase << 
"deserializeManifest: revocation manifest (" 
  822                        auto const st = buildManifestObject(
 
  828                        auto const m = toString(st);
 
  832                        BEAST_EXPECT(
manifest->masterKey == pk);
 
  836                        BEAST_EXPECT(!
manifest->signingKey);
 
  838                        BEAST_EXPECT(
manifest->domain.empty());
 
  839                        BEAST_EXPECT(
manifest->serialized == m);
 
  844                        auto const st = buildManifestObject(
 
  853                        auto const st = buildManifestObject(
 
  862                        auto const st = buildManifestObject(
 
 
  889            st[sfPublicKey] = pk1;
 
  891            st[sfSigningPubKey] = pk2;
 
  908        BEAST_EXPECT(test(
"example.com"));
 
  909        BEAST_EXPECT(test(
"test.example.com"));
 
  910        BEAST_EXPECT(test(
"example-domain.com"));
 
  911        BEAST_EXPECT(test(
"xn--mxavchb.gr"));
 
  912        BEAST_EXPECT(test(
"test.xn--mxavchb.gr"));
 
  913        BEAST_EXPECT(test(
"123.gr"));
 
  914        BEAST_EXPECT(test(
"x.yz"));
 
  915        BEAST_EXPECT(test(
std::string(63, 
'a') + 
".example.com"));
 
  919        BEAST_EXPECT(!test(
"example"));
 
  922        BEAST_EXPECT(!test(
".com"));
 
  923        BEAST_EXPECT(!test(
".example.com"));
 
  926        BEAST_EXPECT(!test(
"example.com."));
 
  929        BEAST_EXPECT(!test(
"-example.com"));
 
  930        BEAST_EXPECT(!test(
"example-.com"));
 
  933        BEAST_EXPECT(!test(
"double..periods.example.com"));
 
  936        BEAST_EXPECT(!test(
"example.x"));
 
  937        BEAST_EXPECT(!test(
"example." + 
std::string(64, 
'a')));
 
  940        BEAST_EXPECT(!test(
"example.com-org"));
 
  941        BEAST_EXPECT(!test(
"bang!.com"));
 
  942        BEAST_EXPECT(!test(
"bang!.example.com"));
 
  945        BEAST_EXPECT(!test(
"a.b"));
 
  948        BEAST_EXPECT(!test(
std::string(64, 
'a') + 
".com"));
 
  949        BEAST_EXPECT(!test(
std::string(64, 
'a') + 
".example.com"));
 
 
  996            auto const fake = s_b2.serialized + 
'\0';
 
 1020            BEAST_EXPECT(!cache.
revoked(pk_a));
 
 1021            BEAST_EXPECT(s_aMax.revoked());
 
 1032            BEAST_EXPECT(cache.
revoked(pk_a));
 
 
 
testcase_t testcase
Memberspace for declaring test cases.
 
void fail(String const &reason, char const *file, int line)
Record a failure.
 
Remembers manifests with the highest sequence number.
 
std::optional< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
 
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
 
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
 
bool load(DatabaseCon &dbCon, std::string const &dbTable, std::string const &configManifest, std::vector< std::string > const &configRevocation)
Populate manifest cache with manifests in database and config.
 
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted)
Save cached manifests to database.
 
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
 
void add(Serializer &s) const override
 
void addWithoutSigningFields(Serializer &s) const
 
std::size_t size() const noexcept
 
void const * data() const noexcept
 
Slice slice() const noexcept
 
void testManifestVersioning()
 
void testValidatorToken()
 
static PublicKey randomNode()
 
std::string makeRevocationString(SecretKey const &sk, KeyType type, bool invalidSig=false)
 
void run() override
Runs the suite.
 
void testManifestDomainNames()
 
Manifest makeManifest(SecretKey const &sk, KeyType type, SecretKey const &ssk, KeyType stype, int seq, bool invalidSig=false)
 
static void setupDatabaseDir(boost::filesystem::path const &dbPath)
 
static PublicKey randomMasterKey()
 
static boost::filesystem::path getDatabasePath()
 
static void cleanupDatabaseDir(boost::filesystem::path const &dbPath)
 
Manifest makeRevocation(SecretKey const &sk, KeyType type, bool invalidSig=false)
 
std::string makeManifestString(PublicKey const &pk, SecretKey const &sk, PublicKey const &spk, SecretKey const &ssk, int seq)
 
Manifest clone(Manifest const &m)
 
void testLoadStore(ManifestCache &m)
 
void testManifestDeserialization()
 
A transaction testing environment.
 
beast::Journal const journal
 
ManualTimeKeeper & timeKeeper()
 
Set the regular signature on a JTx.
 
void sign(Json::Value &jv, Account const &account, Json::Value &sigObject)
Sign automatically into a specific Json field of the jv object.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
 
std::optional< Manifest > deserializeManifest(Slice s, beast::Journal journal)
Constructs Manifest from serialized string.
 
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
 
Seed randomSeed()
Create a seed using secure random numbers.
 
std::unique_ptr< DatabaseCon > makeTestWalletDB(DatabaseCon::Setup const &setup, std::string const &dbname, beast::Journal j)
makeTestWalletDB Opens a test wallet database with an arbitrary name.
 
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
 
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
 
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
 
std::string strHex(FwdIt begin, FwdIt end)
 
@ badMasterKey
The master key is not acceptable to us.
 
@ stale
Sequence is too old.
 
@ accepted
Manifest is valid.
 
@ badEphemeralKey
The ephemeral key is not acceptable to us.
 
@ invalid
Timely, but invalid signature.
 
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
 
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
 
std::string base64_encode(std::uint8_t const *data, std::size_t len)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
 
std::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob, beast::Journal journal)
 
boost::filesystem::path dataDir
 
std::string serialized
The manifest in serialized form.
 
std::uint32_t sequence
The sequence number of this manifest.
 
std::string domain
The domain, if one was specified in the manifest; empty otherwise.
 
std::optional< PublicKey > signingKey
The ephemeral key associated with this manifest.
 
PublicKey masterKey
The master key associated with this manifest.
 
Set the sequence number on a JTx.