mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Unit test simulated ledgers can do signature verification.
This commit is contained in:
committed by
Tom Ritchford
parent
436ded68b7
commit
6d91d02c62
@@ -1440,9 +1440,6 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\Ledger.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\Ledger.test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerCleaner.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -1487,6 +1484,9 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\OrderBookIterator.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\tests\Ledger_test.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\TransactionStateSF.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
@@ -1681,6 +1681,11 @@
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\peers\UniqueNodeList.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\tests\common_ledger.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\tests\common_ledger.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\transactors\CancelOffer.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
||||
@@ -286,6 +286,9 @@
|
||||
<Filter Include="ripple\app\ledger">
|
||||
<UniqueIdentifier>{CE126498-A44D-30A2-345B-0F672BCDF947}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ripple\app\ledger\tests">
|
||||
<UniqueIdentifier>{55A76B5B-A18E-E655-1A07-9492C6F8F356}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ripple\app\main">
|
||||
<UniqueIdentifier>{91D5931B-D981-52BC-BC12-08DA9F7BF606}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -307,6 +310,9 @@
|
||||
<Filter Include="ripple\app\peers">
|
||||
<UniqueIdentifier>{07831F2A-6752-E81C-87AF-4D47D425BE8E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ripple\app\tests">
|
||||
<UniqueIdentifier>{2E791662-6ED0-D1E1-03A4-0CB35473EC56}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ripple\app\transactors">
|
||||
<UniqueIdentifier>{418BEF0D-AAAB-C368-7D9E-0A97636DE5A6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@@ -2259,9 +2265,6 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\Ledger.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\Ledger.test.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\LedgerCleaner.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
@@ -2316,6 +2319,9 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\ledger\OrderBookIterator.h">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\tests\Ledger_test.cpp">
|
||||
<Filter>ripple\app\ledger\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\app\ledger\TransactionStateSF.cpp">
|
||||
<Filter>ripple\app\ledger</Filter>
|
||||
</ClCompile>
|
||||
@@ -2547,6 +2553,12 @@
|
||||
<ClInclude Include="..\..\src\ripple\app\peers\UniqueNodeList.h">
|
||||
<Filter>ripple\app\peers</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\tests\common_ledger.cpp">
|
||||
<Filter>ripple\app\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\app\tests\common_ledger.h">
|
||||
<Filter>ripple\app\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\app\transactors\CancelOffer.cpp">
|
||||
<Filter>ripple\app\transactors</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/consensus/LedgerConsensus.h>
|
||||
#include <ripple/app/ledger/LedgerTiming.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <ripple/app/transactors/Transactor.h>
|
||||
#include <ripple/basics/seconds_clock.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/protocol/RippleAddress.h>
|
||||
#include <ripple/protocol/STParsedJSON.h>
|
||||
#include <ripple/protocol/TxFlags.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Ledger_test : public beast::unit_test::suite
|
||||
{
|
||||
using TestAccount = std::pair<RippleAddress, unsigned>;
|
||||
|
||||
struct Amount
|
||||
{
|
||||
Amount (double value_, std::string currency_, TestAccount issuer_)
|
||||
: value(value_)
|
||||
, currency(currency_)
|
||||
, issuer(issuer_)
|
||||
{
|
||||
}
|
||||
|
||||
double value;
|
||||
std::string currency;
|
||||
TestAccount issuer;
|
||||
|
||||
Json::Value
|
||||
getJson() const
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["currency"] = currency;
|
||||
tx_json["issuer"] = issuer.first.humanAccountID();
|
||||
tx_json["value"] = std::to_string(value);
|
||||
return tx_json;
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function to parse a transaction in Json, sign it with account,
|
||||
// and return it as a STTx
|
||||
STTx
|
||||
parseTransaction(TestAccount& account, Json::Value const& tx_json)
|
||||
{
|
||||
STParsedJSONObject parsed("tx_json", tx_json);
|
||||
std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
|
||||
expect(sopTrans != nullptr);
|
||||
sopTrans->setFieldVL(sfSigningPubKey, account.first.getAccountPublic());
|
||||
return STTx(*sopTrans);
|
||||
}
|
||||
|
||||
// Helper function to apply a transaction to a ledger
|
||||
void
|
||||
applyTransaction(Ledger::pointer const& ledger, STTx const& tx)
|
||||
{
|
||||
TransactionEngine engine(ledger);
|
||||
bool didApply = false;
|
||||
auto r = engine.applyTransaction(tx, tapOPEN_LEDGER | tapNO_CHECK_SIGN,
|
||||
didApply);
|
||||
expect(r == tesSUCCESS);
|
||||
expect(didApply);
|
||||
}
|
||||
|
||||
// Create genesis ledger from a start amount in drops, and the public
|
||||
// master RippleAddress
|
||||
Ledger::pointer
|
||||
createGenesisLedger(std::uint64_t start_amount_drops, TestAccount const& master)
|
||||
{
|
||||
Ledger::pointer ledger = std::make_shared<Ledger>(master.first,
|
||||
start_amount_drops);
|
||||
ledger->updateHash();
|
||||
ledger->setClosed();
|
||||
expect(ledger->assertSane());
|
||||
return ledger;
|
||||
}
|
||||
|
||||
// Create an account represented by public RippleAddress and private
|
||||
// RippleAddress
|
||||
TestAccount
|
||||
createAccount()
|
||||
{
|
||||
static RippleAddress const seed
|
||||
= RippleAddress::createSeedGeneric ("masterpassphrase");
|
||||
static RippleAddress const generator
|
||||
= RippleAddress::createGeneratorPublic (seed);
|
||||
static int iSeq = -1;
|
||||
++iSeq;
|
||||
return std::make_pair(RippleAddress::createAccountPublic(generator, iSeq),
|
||||
std::uint64_t(0));
|
||||
}
|
||||
|
||||
void
|
||||
freezeAccount(TestAccount& account, Ledger::pointer const& ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "AccountSet";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = account.first.humanAccountID();
|
||||
tx_json["SetFlag"] = asfGlobalFreeze;
|
||||
tx_json["Sequence"] = ++account.second;
|
||||
STTx tx = parseTransaction(account, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
void
|
||||
unfreezeAccount(TestAccount& account, Ledger::pointer const& ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "AccountSet";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = account.first.humanAccountID();
|
||||
tx_json["ClearFlag"] = asfGlobalFreeze;
|
||||
tx_json["Sequence"] = ++account.second;
|
||||
STTx tx = parseTransaction(account, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
void
|
||||
makePayment(TestAccount& from, TestAccount const& to,
|
||||
std::uint64_t amountDrops,
|
||||
Ledger::pointer const& ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["Account"] = from.first.humanAccountID();
|
||||
tx_json["Amount"] = std::to_string(amountDrops);
|
||||
tx_json["Destination"] = to.first.humanAccountID();
|
||||
tx_json["TransactionType"] = "Payment";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Sequence"] = ++from.second;
|
||||
tx_json["Flags"] = tfUniversal;
|
||||
STTx tx = parseTransaction(from, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
void
|
||||
makePayment(TestAccount& from, TestAccount const& to,
|
||||
std::string const& currency, std::string const& amount,
|
||||
Ledger::pointer const& ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["Account"] = from.first.humanAccountID();
|
||||
tx_json["Amount"] = Amount(std::stod(amount), currency, to).getJson();
|
||||
tx_json["Destination"] = to.first.humanAccountID();
|
||||
tx_json["TransactionType"] = "Payment";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Sequence"] = ++from.second;
|
||||
tx_json["Flags"] = tfUniversal;
|
||||
STTx tx = parseTransaction(from, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
void
|
||||
createOffer(TestAccount& from, Amount const& in, Amount const& out,
|
||||
Ledger::pointer ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "OfferCreate";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = from.first.humanAccountID();
|
||||
tx_json["TakerPays"] = in.getJson();
|
||||
tx_json["TakerGets"] = out.getJson();
|
||||
tx_json["Sequence"] = ++from.second;
|
||||
STTx tx = parseTransaction(from, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
// As currently implemented, this will cancel only the last offer made
|
||||
// from this account.
|
||||
void
|
||||
cancelOffer(TestAccount& from, Ledger::pointer ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "OfferCancel";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = from.first.humanAccountID();
|
||||
tx_json["OfferSequence"] = from.second;
|
||||
tx_json["Sequence"] = ++from.second;
|
||||
STTx tx = parseTransaction(from, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
void
|
||||
makeTrustSet(TestAccount& from, TestAccount const& issuer,
|
||||
std::string const& currency, double amount,
|
||||
Ledger::pointer const& ledger)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["Account"] = from.first.humanAccountID();
|
||||
Json::Value& limitAmount = tx_json["LimitAmount"];
|
||||
limitAmount["currency"] = currency;
|
||||
limitAmount["issuer"] = issuer.first.humanAccountID();
|
||||
limitAmount["value"] = std::to_string(amount);
|
||||
tx_json["TransactionType"] = "TrustSet";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Sequence"] = ++from.second;
|
||||
tx_json["Flags"] = tfClearNoRipple;
|
||||
STTx tx = parseTransaction(from, tx_json);
|
||||
applyTransaction(ledger, tx);
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
close_and_advance(Ledger::pointer ledger, Ledger::pointer LCL)
|
||||
{
|
||||
SHAMap::pointer set = ledger->peekTransactionMap();
|
||||
CanonicalTXSet retriableTransactions(set->getHash());
|
||||
Ledger::pointer newLCL = std::make_shared<Ledger>(false, *LCL);
|
||||
// Set up to write SHAMap changes to our database,
|
||||
// perform updates, extract changes
|
||||
applyTransactions(set, newLCL, newLCL, retriableTransactions, false);
|
||||
newLCL->updateSkipList();
|
||||
newLCL->setClosed();
|
||||
newLCL->peekAccountStateMap()->flushDirty(
|
||||
hotACCOUNT_NODE, newLCL->getLedgerSeq());
|
||||
newLCL->peekTransactionMap()->flushDirty(
|
||||
hotTRANSACTION_NODE, newLCL->getLedgerSeq());
|
||||
using namespace std::chrono;
|
||||
auto const epoch_offset = days(10957); // 2000-01-01
|
||||
std::uint32_t closeTime = time_point_cast<seconds> // now
|
||||
(system_clock::now()-epoch_offset).
|
||||
time_since_epoch().count();
|
||||
int CloseResolution = seconds(LEDGER_TIME_ACCURACY).count();
|
||||
bool closeTimeCorrect = true;
|
||||
newLCL->setAccepted(closeTime, CloseResolution, closeTimeCorrect);
|
||||
return newLCL;
|
||||
}
|
||||
|
||||
void test_genesisLedger ()
|
||||
{
|
||||
std::uint64_t const xrp = std::mega::num;
|
||||
|
||||
// Create master account
|
||||
auto master = createAccount();
|
||||
|
||||
// Create genesis ledger
|
||||
Ledger::pointer LCL = createGenesisLedger(100000*xrp, master);
|
||||
|
||||
// Create open scratch ledger
|
||||
Ledger::pointer ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
// Create user accounts
|
||||
auto gw1 = createAccount();
|
||||
auto gw2 = createAccount();
|
||||
auto gw3 = createAccount();
|
||||
auto alice = createAccount();
|
||||
auto mark = createAccount();
|
||||
|
||||
// Fund gw1, gw2, gw3, alice, mark from master
|
||||
makePayment(master, gw1, 5000*xrp, ledger);
|
||||
makePayment(master, gw2, 4000*xrp, ledger);
|
||||
makePayment(master, gw3, 3000*xrp, ledger);
|
||||
makePayment(master, alice, 2000*xrp, ledger);
|
||||
makePayment(master, mark, 1000*xrp, ledger);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
// alice trusts FOO/gw1
|
||||
makeTrustSet(alice, gw1, "FOO", 1, ledger);
|
||||
|
||||
// mark trusts FOO/gw2
|
||||
makeTrustSet(mark, gw2, "FOO", 1, ledger);
|
||||
|
||||
// mark trusts FOO/gw3
|
||||
makeTrustSet(mark, gw3, "FOO", 1, ledger);
|
||||
|
||||
// gw2 pays mark with FOO
|
||||
makePayment(gw2, mark, "FOO", ".1", ledger);
|
||||
|
||||
// gw3 pays mark with FOO
|
||||
makePayment(gw3, mark, "FOO", ".2", ledger);
|
||||
|
||||
// gw1 pays alice with FOO
|
||||
makePayment(gw1, alice, "FOO", ".3", ledger);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
createOffer(mark, Amount(1, "FOO", gw1), Amount(1, "FOO", gw2), ledger);
|
||||
createOffer(mark, Amount(1, "FOO", gw2), Amount(1, "FOO", gw3), ledger);
|
||||
cancelOffer(mark, ledger);
|
||||
freezeAccount(alice, ledger);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
makePayment(alice, mark, 1*xrp, ledger);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
}
|
||||
|
||||
void test_getQuality ()
|
||||
{
|
||||
uint256 uBig (
|
||||
"D2DC44E5DC189318DB36EF87D2104CDF0A0FE3A4B698BEEE55038D7EA4C68000");
|
||||
expect (6125895493223874560 == getQuality (uBig));
|
||||
}
|
||||
public:
|
||||
void run ()
|
||||
{
|
||||
test_genesisLedger ();
|
||||
test_getQuality ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Ledger,ripple_app,ripple);
|
||||
|
||||
} // ripple
|
||||
149
src/ripple/app/ledger/tests/Ledger_test.cpp
Normal file
149
src/ripple/app/ledger/tests/Ledger_test.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/tests/common_ledger.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
class Ledger_test : public beast::unit_test::suite
|
||||
{
|
||||
void test_genesisLedger (bool sign)
|
||||
{
|
||||
std::uint64_t const xrp = std::mega::num;
|
||||
|
||||
auto master = createAccount ("masterpassphrase");
|
||||
|
||||
Ledger::pointer LCL = createGenesisLedger(100000*xrp, master);
|
||||
|
||||
Ledger::pointer ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
// User accounts
|
||||
auto gw1 = createAccount ("gw1");
|
||||
expect (gw1.pk != master.pk, "gw1.pk != master.pk");
|
||||
expect (gw1.sk != master.sk, "gw1.sk != master.sk");
|
||||
auto gw2 = createAccount ("gw2");
|
||||
auto gw3 = createAccount ("gw3");
|
||||
auto alice = createAccount ("alice");
|
||||
auto mark = createAccount ("mark");
|
||||
|
||||
// Fund gw1, gw2, gw3, alice, mark from master
|
||||
makeAndApplyPayment(master, gw1, 5000 * xrp, ledger, sign);
|
||||
makeAndApplyPayment(master, gw2, 4000 * xrp, ledger, sign);
|
||||
makeAndApplyPayment(master, gw3, 3000 * xrp, ledger, sign);
|
||||
makeAndApplyPayment(master, alice, 2000 * xrp, ledger, sign);
|
||||
makeAndApplyPayment(master, mark, 1000 * xrp, ledger, sign);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
// alice trusts FOO/gw1
|
||||
makeTrustSet (alice, gw1, "FOO", 1, ledger, sign);
|
||||
|
||||
// mark trusts FOO/gw2
|
||||
makeTrustSet (mark, gw2, "FOO", 1, ledger, sign);
|
||||
|
||||
// mark trusts FOO/gw3
|
||||
makeTrustSet (mark, gw3, "FOO", 1, ledger, sign);
|
||||
|
||||
// gw2 pays mark with FOO
|
||||
makeAndApplyPayment(gw2, mark, "FOO", ".1", ledger, sign);
|
||||
|
||||
// gw3 pays mark with FOO
|
||||
makeAndApplyPayment(gw3, mark, "FOO", ".2", ledger, sign);
|
||||
|
||||
// gw1 pays alice with FOO
|
||||
makeAndApplyPayment(gw1, alice, "FOO", ".3", ledger, sign);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
createOffer (mark, Amount (1, "FOO", gw1), Amount (1, "FOO", gw2), ledger, sign);
|
||||
createOffer (mark, Amount (1, "FOO", gw2), Amount (1, "FOO", gw3), ledger, sign);
|
||||
cancelOffer (mark, ledger, sign);
|
||||
freezeAccount (alice, ledger, sign);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
makeAndApplyPayment(alice, mark, 1 * xrp, ledger, sign);
|
||||
|
||||
LCL = close_and_advance(ledger, LCL);
|
||||
ledger = std::make_shared<Ledger>(false, *LCL);
|
||||
|
||||
pass ();
|
||||
}
|
||||
|
||||
void test_unsigned_fails ()
|
||||
{
|
||||
std::uint64_t const xrp = std::mega::num;
|
||||
|
||||
auto master = createAccount ("masterpassphrase");
|
||||
|
||||
Ledger::pointer LCL = createGenesisLedger (100000 * xrp, master);
|
||||
|
||||
Ledger::pointer ledger = std::make_shared<Ledger> (false, *LCL);
|
||||
|
||||
auto gw1 = createAccount ("gw1");
|
||||
|
||||
auto tx = getPaymentTx(master, gw1, 5000 * xrp, false);
|
||||
|
||||
try
|
||||
{
|
||||
applyTransaction (ledger, tx, true);
|
||||
fail ("apply unsigned transaction should fail");
|
||||
}
|
||||
catch (std::runtime_error const& e)
|
||||
{
|
||||
if (std::string (e.what()) != "r != tesSUCCESS")
|
||||
throw std::runtime_error(e.what());
|
||||
}
|
||||
|
||||
pass ();
|
||||
}
|
||||
|
||||
void test_getQuality ()
|
||||
{
|
||||
uint256 uBig (
|
||||
"D2DC44E5DC189318DB36EF87D2104CDF0A0FE3A4B698BEEE55038D7EA4C68000");
|
||||
expect (6125895493223874560 == getQuality (uBig));
|
||||
|
||||
pass ();
|
||||
}
|
||||
public:
|
||||
void run ()
|
||||
{
|
||||
testcase ("genesisLedger signed transactions");
|
||||
test_genesisLedger (true);
|
||||
|
||||
testcase ("genesisLedger unsigned transactions");
|
||||
test_genesisLedger (false);
|
||||
|
||||
testcase ("unsigned invalid");
|
||||
test_unsigned_fails ();
|
||||
|
||||
testcase ("getQuality");
|
||||
test_getQuality ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Ledger,ripple_app,ripple);
|
||||
|
||||
} // test
|
||||
} // ripple
|
||||
262
src/ripple/app/tests/common_ledger.cpp
Normal file
262
src/ripple/app/tests/common_ledger.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/tests/common_ledger.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
Amount::Amount(double value_, std::string currency_, TestAccount issuer_)
|
||||
: value(value_)
|
||||
, currency(currency_)
|
||||
, issuer(issuer_)
|
||||
{
|
||||
}
|
||||
|
||||
Json::Value
|
||||
Amount::getJson() const
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["currency"] = currency;
|
||||
tx_json["issuer"] = issuer.pk.humanAccountID();
|
||||
tx_json["value"] = std::to_string(value);
|
||||
return tx_json;
|
||||
}
|
||||
|
||||
// Helper function to parse a transaction in Json, sign it with account,
|
||||
// and return it as a STTx
|
||||
STTx
|
||||
parseTransaction(TestAccount& account, Json::Value const& tx_json, bool sign)
|
||||
{
|
||||
STParsedJSONObject parsed("tx_json", tx_json);
|
||||
std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
|
||||
if (sopTrans == nullptr)
|
||||
throw std::runtime_error(
|
||||
"sopTrans == nullptr");
|
||||
sopTrans->setFieldVL(sfSigningPubKey, account.pk.getAccountPublic());
|
||||
auto tx = STTx(*sopTrans);
|
||||
if (sign)
|
||||
tx.sign(account.sk);
|
||||
return tx;
|
||||
}
|
||||
|
||||
// Helper function to apply a transaction to a ledger
|
||||
void
|
||||
applyTransaction(Ledger::pointer const& ledger, STTx const& tx, bool check)
|
||||
{
|
||||
TransactionEngine engine(ledger);
|
||||
bool didApply = false;
|
||||
auto r = engine.applyTransaction(tx, tapOPEN_LEDGER | (check ? tapNONE : tapNO_CHECK_SIGN),
|
||||
didApply);
|
||||
if (r != tesSUCCESS)
|
||||
throw std::runtime_error(
|
||||
"r != tesSUCCESS");
|
||||
if (!didApply)
|
||||
throw std::runtime_error(
|
||||
"didApply");
|
||||
}
|
||||
|
||||
// Create genesis ledger from a start amount in drops, and the public
|
||||
// master RippleAddress
|
||||
Ledger::pointer
|
||||
createGenesisLedger(std::uint64_t start_amount_drops, TestAccount const& master)
|
||||
{
|
||||
Ledger::pointer ledger = std::make_shared<Ledger>(master.pk,
|
||||
start_amount_drops);
|
||||
ledger->updateHash();
|
||||
ledger->setClosed();
|
||||
if (!ledger->assertSane())
|
||||
throw std::runtime_error(
|
||||
"! ledger->assertSane()");
|
||||
return ledger;
|
||||
}
|
||||
|
||||
// Create an account represented by public RippleAddress and private
|
||||
// RippleAddress
|
||||
TestAccount
|
||||
createAccount(std::string const& passphrase)
|
||||
{
|
||||
RippleAddress const seed
|
||||
= RippleAddress::createSeedGeneric(passphrase);
|
||||
RippleAddress const generator
|
||||
= RippleAddress::createGeneratorPublic(seed);
|
||||
|
||||
return {
|
||||
std::move(RippleAddress::createAccountPublic(generator, 0)),
|
||||
std::move(RippleAddress::createAccountPrivate(generator, seed, 0)),
|
||||
std::uint64_t(0)
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
freezeAccount(TestAccount& account, Ledger::pointer const& ledger, bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "AccountSet";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = account.pk.humanAccountID();
|
||||
tx_json["SetFlag"] = asfGlobalFreeze;
|
||||
tx_json["Sequence"] = ++account.sequence;
|
||||
STTx tx = parseTransaction(account, tx_json, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
}
|
||||
|
||||
void
|
||||
unfreezeAccount(TestAccount& account, Ledger::pointer const& ledger, bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "AccountSet";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = account.pk.humanAccountID();
|
||||
tx_json["ClearFlag"] = asfGlobalFreeze;
|
||||
tx_json["Sequence"] = ++account.sequence;
|
||||
STTx tx = parseTransaction(account, tx_json, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
}
|
||||
|
||||
STTx
|
||||
getPaymentTx(TestAccount& from, TestAccount const& to,
|
||||
std::uint64_t amountDrops,
|
||||
bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["Account"] = from.pk.humanAccountID();
|
||||
tx_json["Amount"] = std::to_string(amountDrops);
|
||||
tx_json["Destination"] = to.pk.humanAccountID();
|
||||
tx_json["TransactionType"] = "Payment";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Sequence"] = ++from.sequence;
|
||||
tx_json["Flags"] = tfUniversal;
|
||||
return parseTransaction(from, tx_json, sign);
|
||||
}
|
||||
|
||||
STTx
|
||||
makeAndApplyPayment(TestAccount& from, TestAccount const& to,
|
||||
std::uint64_t amountDrops,
|
||||
Ledger::pointer const& ledger, bool sign)
|
||||
{
|
||||
auto tx = getPaymentTx(from, to, amountDrops, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
return tx;
|
||||
}
|
||||
|
||||
STTx
|
||||
getPaymentTx(TestAccount& from, TestAccount const& to,
|
||||
std::string const& currency, std::string const& amount,
|
||||
bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["Account"] = from.pk.humanAccountID();
|
||||
tx_json["Amount"] = Amount(std::stod(amount), currency, to).getJson();
|
||||
tx_json["Destination"] = to.pk.humanAccountID();
|
||||
tx_json["TransactionType"] = "Payment";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Sequence"] = ++from.sequence;
|
||||
tx_json["Flags"] = tfUniversal;
|
||||
return parseTransaction(from, tx_json, sign);
|
||||
}
|
||||
|
||||
STTx
|
||||
makeAndApplyPayment(TestAccount& from, TestAccount const& to,
|
||||
std::string const& currency, std::string const& amount,
|
||||
Ledger::pointer const& ledger, bool sign)
|
||||
{
|
||||
auto tx = getPaymentTx(from, to, currency, amount, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
return tx;
|
||||
}
|
||||
|
||||
void
|
||||
createOffer(TestAccount& from, Amount const& in, Amount const& out,
|
||||
Ledger::pointer ledger, bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "OfferCreate";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = from.pk.humanAccountID();
|
||||
tx_json["TakerPays"] = in.getJson();
|
||||
tx_json["TakerGets"] = out.getJson();
|
||||
tx_json["Sequence"] = ++from.sequence;
|
||||
STTx tx = parseTransaction(from, tx_json, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
}
|
||||
|
||||
// As currently implemented, this will cancel only the last offer made
|
||||
// from this account.
|
||||
void
|
||||
cancelOffer(TestAccount& from, Ledger::pointer ledger, bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["TransactionType"] = "OfferCancel";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Account"] = from.pk.humanAccountID();
|
||||
tx_json["OfferSequence"] = from.sequence;
|
||||
tx_json["Sequence"] = ++from.sequence;
|
||||
STTx tx = parseTransaction(from, tx_json, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
}
|
||||
|
||||
void
|
||||
makeTrustSet(TestAccount& from, TestAccount const& issuer,
|
||||
std::string const& currency, double amount,
|
||||
Ledger::pointer const& ledger, bool sign)
|
||||
{
|
||||
Json::Value tx_json;
|
||||
tx_json["Account"] = from.pk.humanAccountID();
|
||||
Json::Value& limitAmount = tx_json["LimitAmount"];
|
||||
limitAmount["currency"] = currency;
|
||||
limitAmount["issuer"] = issuer.pk.humanAccountID();
|
||||
limitAmount["value"] = std::to_string(amount);
|
||||
tx_json["TransactionType"] = "TrustSet";
|
||||
tx_json["Fee"] = std::to_string(10);
|
||||
tx_json["Sequence"] = ++from.sequence;
|
||||
tx_json["Flags"] = tfClearNoRipple;
|
||||
STTx tx = parseTransaction(from, tx_json, sign);
|
||||
applyTransaction(ledger, tx, sign);
|
||||
}
|
||||
|
||||
Ledger::pointer
|
||||
close_and_advance(Ledger::pointer ledger, Ledger::pointer LCL)
|
||||
{
|
||||
SHAMap::pointer set = ledger->peekTransactionMap();
|
||||
CanonicalTXSet retriableTransactions(set->getHash());
|
||||
Ledger::pointer newLCL = std::make_shared<Ledger>(false, *LCL);
|
||||
// Set up to write SHAMap changes to our database,
|
||||
// perform updates, extract changes
|
||||
applyTransactions(set, newLCL, newLCL, retriableTransactions, false);
|
||||
newLCL->updateSkipList();
|
||||
newLCL->setClosed();
|
||||
newLCL->peekAccountStateMap()->flushDirty(
|
||||
hotACCOUNT_NODE, newLCL->getLedgerSeq());
|
||||
newLCL->peekTransactionMap()->flushDirty(
|
||||
hotTRANSACTION_NODE, newLCL->getLedgerSeq());
|
||||
using namespace std::chrono;
|
||||
auto const epoch_offset = days(10957); // 2000-01-01
|
||||
std::uint32_t closeTime = time_point_cast<seconds> // now
|
||||
(system_clock::now() - epoch_offset).
|
||||
time_since_epoch().count();
|
||||
int closeResolution = seconds(LEDGER_TIME_ACCURACY).count();
|
||||
bool closeTimeCorrect = true;
|
||||
newLCL->setAccepted(closeTime, closeResolution, closeTimeCorrect);
|
||||
return newLCL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
126
src/ripple/app/tests/common_ledger.h
Normal file
126
src/ripple/app/tests/common_ledger.h
Normal file
@@ -0,0 +1,126 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_TESTS_COMMON_LEDGER_H_INCLUDED
|
||||
#define RIPPLE_APP_TESTS_COMMON_LEDGER_H_INCLUDED
|
||||
|
||||
#include <ripple/app/ledger/Ledger.h>
|
||||
#include <ripple/app/consensus/LedgerConsensus.h>
|
||||
#include <ripple/app/ledger/LedgerTiming.h>
|
||||
#include <ripple/app/misc/CanonicalTXSet.h>
|
||||
#include <ripple/app/transactors/Transactor.h>
|
||||
#include <ripple/basics/seconds_clock.h>
|
||||
#include <ripple/json/json_value.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/protocol/RippleAddress.h>
|
||||
#include <ripple/protocol/STParsedJSON.h>
|
||||
#include <ripple/protocol/TxFlags.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
struct TestAccount
|
||||
{
|
||||
RippleAddress pk;
|
||||
RippleAddress sk;
|
||||
unsigned sequence;
|
||||
};
|
||||
|
||||
struct Amount
|
||||
{
|
||||
Amount(double value_, std::string currency_, TestAccount issuer_);
|
||||
|
||||
Json::Value
|
||||
getJson() const;
|
||||
|
||||
private:
|
||||
double value;
|
||||
std::string currency;
|
||||
TestAccount issuer;
|
||||
};
|
||||
|
||||
// Helper function to parse a transaction in Json, sign it with account,
|
||||
// and return it as a STTx
|
||||
STTx
|
||||
parseTransaction(TestAccount& account, Json::Value const& tx_json, bool sign = true);
|
||||
|
||||
// Helper function to apply a transaction to a ledger
|
||||
void
|
||||
applyTransaction(Ledger::pointer const& ledger, STTx const& tx, bool check = true);
|
||||
|
||||
// Create genesis ledger from a start amount in drops, and the public
|
||||
// master RippleAddress
|
||||
Ledger::pointer
|
||||
createGenesisLedger(std::uint64_t start_amount_drops, TestAccount const& master);
|
||||
|
||||
// Create an account represented by public RippleAddress and private
|
||||
// RippleAddress
|
||||
TestAccount
|
||||
createAccount(std::string const& passphrase);
|
||||
|
||||
void
|
||||
freezeAccount(TestAccount& account, Ledger::pointer const& ledger, bool sign = true);
|
||||
|
||||
void
|
||||
unfreezeAccount(TestAccount& account, Ledger::pointer const& ledger, bool sign = true);
|
||||
|
||||
STTx
|
||||
getPaymentTx(TestAccount& from, TestAccount const& to,
|
||||
std::uint64_t amountDrops,
|
||||
bool sign = true);
|
||||
|
||||
STTx
|
||||
makeAndApplyPayment(TestAccount& from, TestAccount const& to,
|
||||
std::uint64_t amountDrops,
|
||||
Ledger::pointer const& ledger, bool sign = true);
|
||||
|
||||
STTx
|
||||
getPaymentTx(TestAccount& from, TestAccount const& to,
|
||||
std::string const& currency, std::string const& amount,
|
||||
bool sign = true);
|
||||
|
||||
STTx
|
||||
makeAndApplyPayment(TestAccount& from, TestAccount const& to,
|
||||
std::string const& currency, std::string const& amount,
|
||||
Ledger::pointer const& ledger, bool sign = true);
|
||||
|
||||
void
|
||||
createOffer(TestAccount& from, Amount const& in, Amount const& out,
|
||||
Ledger::pointer ledger, bool sign = true);
|
||||
|
||||
// As currently implemented, this will cancel only the last offer made
|
||||
// from this account.
|
||||
void
|
||||
cancelOffer(TestAccount& from, Ledger::pointer ledger, bool sign = true);
|
||||
|
||||
void
|
||||
makeTrustSet(TestAccount& from, TestAccount const& issuer,
|
||||
std::string const& currency, double amount,
|
||||
Ledger::pointer const& ledger, bool sign = true);
|
||||
|
||||
Ledger::pointer
|
||||
close_and_advance(Ledger::pointer ledger, Ledger::pointer LCL);
|
||||
|
||||
} // test
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -20,5 +20,7 @@
|
||||
#include <BeastConfig.h>
|
||||
|
||||
#include <ripple/app/ledger/Ledger.cpp>
|
||||
#include <ripple/app/ledger/Ledger.test.cpp>
|
||||
#include <ripple/app/misc/AccountState.cpp>
|
||||
|
||||
#include <ripple/app/tests/common_ledger.cpp>
|
||||
#include <ripple/app/ledger/tests/Ledger_test.cpp>
|
||||
|
||||
Reference in New Issue
Block a user