mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
STObject::applyTemplate() throws with description of error:
The `STObject` member function `setType()` has been renamed to applyTemplate() and modified to throw if there is a template mismatch. The error description in the exception is, in certain cases, used, to better indicate why a particular transaction was considered ill formed. Fixes #2585.
This commit is contained in:
committed by
Nik Bougalis
parent
c354809e1c
commit
ad5c5f1969
@@ -363,7 +363,7 @@ public:
|
||||
|
||||
BEAST_EXPECT(st[sf1] == 1);
|
||||
BEAST_EXPECT(st[sf2] == 2);
|
||||
except<missing_field_error>([&]()
|
||||
except<STObject::FieldErr>([&]()
|
||||
{ st[sf3]; });
|
||||
BEAST_EXPECT(*st[~sf1] == 1);
|
||||
BEAST_EXPECT(*st[~sf2] == 2);
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/protocol/STAmount.h>
|
||||
#include <ripple/protocol/Sign.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/STParsedJSON.h>
|
||||
#include <ripple/protocol/TxFormats.h>
|
||||
#include <ripple/protocol/UintTypes.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
@@ -41,6 +43,9 @@ public:
|
||||
|
||||
testcase ("ed25519 signatures");
|
||||
testSTTx (KeyType::ed25519);
|
||||
|
||||
testcase ("STObject constructor errors");
|
||||
testObjectCtorErrors();
|
||||
}
|
||||
|
||||
void testDeepNesting()
|
||||
@@ -1229,7 +1234,7 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
ripple::SerialIter sit (Slice{payload2, sizeof(payload2)});
|
||||
ripple::SerialIter sit {payload2};
|
||||
auto stx = std::make_shared<ripple::STTx const>(sit);
|
||||
fail("An exception should have been thrown");
|
||||
}
|
||||
@@ -1287,6 +1292,95 @@ public:
|
||||
pass ();
|
||||
}
|
||||
}
|
||||
|
||||
void testObjectCtorErrors ()
|
||||
{
|
||||
auto const kp1 = randomKeyPair (KeyType::secp256k1);
|
||||
auto const id1 = calcAccountID(kp1.first);
|
||||
|
||||
auto const kp2 = randomKeyPair (KeyType::secp256k1);
|
||||
auto const id2 = calcAccountID(kp2.first);
|
||||
|
||||
// Lambda that returns a Payment STObject.
|
||||
auto getPayment = [kp1, id1, id2] ()
|
||||
{
|
||||
// Account id1 pays account id2 10,000 XRP.
|
||||
STObject payment (sfGeneric);
|
||||
payment.setFieldU16 (sfTransactionType, ttPAYMENT);
|
||||
payment.setAccountID (sfAccount, id1);
|
||||
payment.setAccountID (sfDestination, id2);
|
||||
payment.setFieldAmount (sfAmount, STAmount (10000000000ull));
|
||||
payment.setFieldAmount (sfFee, STAmount (10ull));
|
||||
payment.setFieldU32 (sfSequence, 1);
|
||||
payment.setFieldVL (
|
||||
sfSigningPubKey, Slice (kp1.first.data(), kp1.first.size()));
|
||||
return payment;
|
||||
};
|
||||
{
|
||||
// Verify that getPayment() returns a viable Payment.
|
||||
std::string got;
|
||||
try
|
||||
{
|
||||
STTx {getPayment()};
|
||||
}
|
||||
catch (STTx::FieldErr const& err)
|
||||
{
|
||||
got = err.what();
|
||||
}
|
||||
BEAST_EXPECT (got.empty());
|
||||
}
|
||||
{
|
||||
// Make a payment with a defaulted PathSet field, which is invalid.
|
||||
STObject defaultPath {getPayment()};
|
||||
defaultPath.setFieldPathSet (sfPaths, STPathSet{});
|
||||
|
||||
std::string got;
|
||||
try
|
||||
{
|
||||
STTx {std::move (defaultPath)};
|
||||
}
|
||||
catch (STTx::FieldErr const& err)
|
||||
{
|
||||
got = err.what();
|
||||
}
|
||||
BEAST_EXPECT (
|
||||
got == "Field 'Paths' may not be explicitly set to default.");
|
||||
}
|
||||
{
|
||||
// Make a Payment with an extra "SignerWeight" field.
|
||||
STObject extraField {getPayment()};
|
||||
extraField.setFieldU16 (sfSignerWeight, 7);
|
||||
|
||||
std::string got;
|
||||
try
|
||||
{
|
||||
STTx {std::move (extraField)};
|
||||
}
|
||||
catch (STTx::FieldErr const& err)
|
||||
{
|
||||
got = err.what();
|
||||
}
|
||||
BEAST_EXPECT (
|
||||
got == "Field 'SignerWeight' found in disallowed location.");
|
||||
}
|
||||
{
|
||||
// Make a Payment that is missing the required Fee field.
|
||||
STObject extraField {getPayment()};
|
||||
extraField.delField (sfFee);
|
||||
|
||||
std::string got;
|
||||
try
|
||||
{
|
||||
STTx {std::move (extraField)};
|
||||
}
|
||||
catch (STTx::FieldErr const& err)
|
||||
{
|
||||
got = err.what();
|
||||
}
|
||||
BEAST_EXPECT (
|
||||
got == "Field 'Fee' is required but missing.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class InnerObjectFormatsSerializer_test : public beast::unit_test::suite
|
||||
|
||||
@@ -38,34 +38,43 @@ public:
|
||||
{
|
||||
testcase ("Deserialization");
|
||||
|
||||
constexpr unsigned char payload1[] =
|
||||
{ // specifies an Ed25519 public key
|
||||
0x72, 0x00, 0x73, 0x21, 0xed, 0x78, 0x00, 0xe6, 0x73, 0x00, 0x72, 0x00, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x88, 0x00, 0xe6, 0x73, 0x38, 0x00, 0x00, 0x8a, 0x00, 0x88, 0x4e, 0x31, 0x30, 0x5f, 0x5f, 0x63,
|
||||
0x78, 0x78, 0x61, 0x62, 0x69, 0x76, 0x31, 0x30, 0x37, 0x5f, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73,
|
||||
0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x00, 0xe6, 0x88, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x53, 0x65, 0x74, 0x65, 0x61, 0x74, 0x65, 0x88, 0x00, 0xe6, 0x88, 0x00, 0xe6,
|
||||
0x73, 0x00, 0x72, 0x00, 0x8a, 0x00, 0x88, 0x00, 0xe6
|
||||
};
|
||||
|
||||
constexpr unsigned char payload2[] =
|
||||
constexpr std::uint8_t payload1[] =
|
||||
{
|
||||
0x73, 0x21, 0xed, 0xff, 0x03, 0x1c, 0xbe, 0x65, 0x22, 0x61, 0x9c, 0x5e, 0x13, 0x12, 0x00, 0x3b,
|
||||
0x43, 0x00, 0x00, 0x00, 0xf7, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x13, 0x13, 0x13,
|
||||
0x3a, 0x27, 0xff
|
||||
// specifies an Ed25519 public key.
|
||||
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x51,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x73,
|
||||
0x21, 0xed, 0x78, 0x00, 0xe6, 0x73, 0x00, 0x72, 0x00, 0x3c, 0x00,
|
||||
0x00, 0x00, 0x88, 0x00, 0xe6, 0x73, 0x38, 0x00, 0x00, 0x8a, 0x00,
|
||||
0x88, 0x4e, 0x31, 0x30, 0x5f, 0x5f, 0x63, 0x78, 0x78, 0x61, 0x62,
|
||||
0x69
|
||||
};
|
||||
|
||||
constexpr unsigned char payload3[] =
|
||||
{ // Has no public key at all
|
||||
0x72, 0x00, 0x76, 0x31, 0x30, 0x37, 0x5f, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x00, 0xe6, 0x88, 0x54, 0x72, 0x75, 0x73, 0x74,
|
||||
0x53, 0x65, 0x74, 0x65, 0x61, 0x74, 0x65, 0x88, 0x00, 0xe6, 0x88, 0x00, 0xe6, 0x73, 0x00, 0x72,
|
||||
0x00, 0x8a, 0x00, 0x88, 0x00, 0xe6
|
||||
constexpr std::uint8_t payload2[] =
|
||||
{
|
||||
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x51,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x73,
|
||||
0x21, 0xed, 0xff, 0x03, 0x1c, 0xbe, 0x65, 0x22, 0x61, 0x9c, 0x5e,
|
||||
0x13, 0x12, 0x00, 0x3b, 0x43, 0x00, 0x00, 0x00, 0xf7, 0x3f, 0x3f,
|
||||
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x3a, 0x27,
|
||||
0xff
|
||||
};
|
||||
|
||||
constexpr std::uint8_t payload3[] =
|
||||
{
|
||||
// Has no public key at all
|
||||
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x51,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
SerialIter sit{payload1, sizeof(payload1)};
|
||||
SerialIter sit {payload1};
|
||||
auto stx = std::make_shared<ripple::STValidation>(sit,
|
||||
[](PublicKey const& pk) {
|
||||
return calcNodeID(pk);
|
||||
@@ -74,12 +83,13 @@ public:
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
BEAST_EXPECT(strcmp(e.what(), "Invalid public key in validation") == 0);
|
||||
BEAST_EXPECT(strcmp(e.what(),
|
||||
"Invalid public key in validation") == 0);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SerialIter sit{payload2, sizeof(payload2)};
|
||||
SerialIter sit {payload2};
|
||||
auto stx = std::make_shared<ripple::STValidation>(sit,
|
||||
[](PublicKey const& pk) {
|
||||
return calcNodeID(pk);
|
||||
@@ -88,12 +98,13 @@ public:
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
BEAST_EXPECT(strcmp(e.what(), "Invalid public key in validation") == 0);
|
||||
BEAST_EXPECT(strcmp(e.what(),
|
||||
"Invalid public key in validation") == 0);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SerialIter sit{payload3, sizeof(payload3)};
|
||||
SerialIter sit {payload3};
|
||||
auto stx = std::make_shared<ripple::STValidation>(sit,
|
||||
[](PublicKey const& pk) {
|
||||
return calcNodeID(pk);
|
||||
@@ -102,8 +113,8 @@ public:
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
log << e.what() << "\n";
|
||||
BEAST_EXPECT(strcmp(e.what(), "Invalid public key in validation") == 0);
|
||||
BEAST_EXPECT(strcmp(e.what(),
|
||||
"Field 'SigningPubKey' is required but missing.") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user