Skip to content

Commit 39730fc

Browse files
committed
Ticket issuing (RIPD-368):
* New CreateTicket transactor to create tickets * New CancelTicket transactor to cancel tickets * Ledger entries for tickets & associated functions * First draft of M-of-N documentation
1 parent 889c0a0 commit 39730fc

19 files changed

+472
-43
lines changed

Builds/VisualStudio2013/RippleD.vcxproj

+6
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,9 @@
23892389
<ClCompile Include="..\..\src\ripple\module\app\transactors\CancelOffer.cpp">
23902390
<ExcludedFromBuild>True</ExcludedFromBuild>
23912391
</ClCompile>
2392+
<ClCompile Include="..\..\src\ripple\module\app\transactors\CancelTicket.cpp">
2393+
<ExcludedFromBuild>True</ExcludedFromBuild>
2394+
</ClCompile>
23922395
<ClCompile Include="..\..\src\ripple\module\app\transactors\Change.cpp">
23932396
<ExcludedFromBuild>True</ExcludedFromBuild>
23942397
</ClCompile>
@@ -2401,6 +2404,9 @@
24012404
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOfferDirect.cpp">
24022405
<ExcludedFromBuild>True</ExcludedFromBuild>
24032406
</ClCompile>
2407+
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateTicket.cpp">
2408+
<ExcludedFromBuild>True</ExcludedFromBuild>
2409+
</ClCompile>
24042410
<ClCompile Include="..\..\src\ripple\module\app\transactors\Payment.cpp">
24052411
<ExcludedFromBuild>True</ExcludedFromBuild>
24062412
</ClCompile>

Builds/VisualStudio2013/RippleD.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -3492,6 +3492,9 @@
34923492
<ClCompile Include="..\..\src\ripple\module\app\transactors\CancelOffer.cpp">
34933493
<Filter>ripple\module\app\transactors</Filter>
34943494
</ClCompile>
3495+
<ClCompile Include="..\..\src\ripple\module\app\transactors\CancelTicket.cpp">
3496+
<Filter>ripple\module\app\transactors</Filter>
3497+
</ClCompile>
34953498
<ClCompile Include="..\..\src\ripple\module\app\transactors\Change.cpp">
34963499
<Filter>ripple\module\app\transactors</Filter>
34973500
</ClCompile>
@@ -3504,6 +3507,9 @@
35043507
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateOfferDirect.cpp">
35053508
<Filter>ripple\module\app\transactors</Filter>
35063509
</ClCompile>
3510+
<ClCompile Include="..\..\src\ripple\module\app\transactors\CreateTicket.cpp">
3511+
<Filter>ripple\module\app\transactors</Filter>
3512+
</ClCompile>
35073513
<ClCompile Include="..\..\src\ripple\module\app\transactors\Payment.cpp">
35083514
<Filter>ripple\module\app\transactors</Filter>
35093515
</ClCompile>

src/ripple/module/app/ledger/Ledger.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -1758,7 +1758,7 @@ uint256 Ledger::getOfferIndex (Account const& account, std::uint32_t uSequence)
17581758
Serializer s (26);
17591759

17601760
s.add16 (spaceOffer); // 2
1761-
s.add160 (account); // 20
1761+
s.add160 (account); // 20
17621762
s.add32 (uSequence); // 4
17631763

17641764
return s.getSHA512Half ();
@@ -1791,6 +1791,18 @@ uint256 Ledger::getRippleStateIndex (
17911791
return s.getSHA512Half ();
17921792
}
17931793

1794+
uint256 Ledger::getTicketIndex (
1795+
Account const& account, std::uint32_t uSequence)
1796+
{
1797+
Serializer s (26);
1798+
1799+
s.add16 (spaceTicket); // 2
1800+
s.add160 (account); // 20
1801+
s.add32 (uSequence); // 4
1802+
1803+
return s.getSHA512Half ();
1804+
}
1805+
17941806
bool Ledger::walkLedger ()
17951807
{
17961808
std::vector <SHAMapMissingNode> missingNodes1;

src/ripple/module/app/ledger/Ledger.h

+7
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,13 @@ class Ledger
414414
Currency const& uTakerGetsCurrency, Account const& uTakerGetsIssuer,
415415
const std::uint64_t & uRate);
416416

417+
//
418+
// Tickets
419+
//
420+
421+
static uint256 getTicketIndex (
422+
Account const& account, std::uint32_t uSequence);
423+
417424
//
418425
// Ripple functions : credit lines
419426
//
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2014 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+
namespace ripple {
21+
22+
class CancelTicket
23+
: public Transactor
24+
{
25+
public:
26+
CancelTicket (
27+
SerializedTransaction const& txn,
28+
TransactionEngineParams params,
29+
TransactionEngine* engine)
30+
: Transactor (
31+
txn,
32+
params,
33+
engine,
34+
deprecatedLogs().journal("CancelTicket"))
35+
{
36+
37+
}
38+
39+
TER doApply () override
40+
{
41+
assert (mTxnAccount);
42+
43+
uint256 const ticketId = mTxn.getFieldH256 (sfTicketID);
44+
45+
SLE::pointer sleTicket = mEngine->view ().entryCache (ltTICKET, ticketId);
46+
47+
if (!sleTicket)
48+
return tecNO_ENTRY;
49+
50+
Account const ticket_owner (sleTicket->getFieldAccount160 (sfAccount));
51+
52+
bool authorized (mTxnAccountID == ticket_owner);
53+
54+
// The target can also always remove a ticket
55+
if (!authorized && sleTicket->isFieldPresent (sfTarget))
56+
authorized = (mTxnAccountID == sleTicket->getFieldAccount160 (sfTarget));
57+
58+
// And finally, anyone can remove an expired ticket
59+
if (!authorized && sleTicket->isFieldPresent (sfExpiration))
60+
{
61+
std::uint32_t const expiration = sleTicket->getFieldU32 (sfExpiration);
62+
63+
if (mEngine->getLedger ()->getParentCloseTimeNC () >= expiration)
64+
authorized = true;
65+
}
66+
67+
if (!authorized)
68+
return tecNO_PERMISSION;
69+
70+
std::uint64_t const hint (sleTicket->getFieldU64 (sfOwnerNode));
71+
72+
TER const result = mEngine->view ().dirDelete (false, hint,
73+
Ledger::getOwnerDirIndex (ticket_owner), ticketId, false, (hint == 0));
74+
75+
mEngine->view ().ownerCountAdjust (ticket_owner, -1);
76+
mEngine->view ().entryDelete (sleTicket);
77+
78+
return result;
79+
}
80+
};
81+
82+
TER
83+
transact_CancelTicket (
84+
SerializedTransaction const& txn,
85+
TransactionEngineParams params,
86+
TransactionEngine* engine)
87+
{
88+
return CancelTicket (txn, params, engine).apply ();
89+
}
90+
91+
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2014 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+
#ifndef RIPPLE_TX_CANCELTICKET_H_INCLUDED
21+
#define RIPPLE_TX_CANCELTICKET_H_INCLUDED
22+
23+
namespace ripple {
24+
25+
26+
}
27+
28+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2014 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+
namespace ripple {
21+
22+
class CreateTicket
23+
: public Transactor
24+
{
25+
public:
26+
CreateTicket (
27+
SerializedTransaction const& txn,
28+
TransactionEngineParams params,
29+
TransactionEngine* engine)
30+
: Transactor (
31+
txn,
32+
params,
33+
engine,
34+
deprecatedLogs().journal("CreateTicket"))
35+
{
36+
37+
}
38+
39+
TER doApply () override
40+
{
41+
assert (mTxnAccount);
42+
43+
// A ticket counts against the reserve of the issuing account, but we check
44+
// the starting balance because we want to allow dipping into the reserve to
45+
// pay fees.
46+
auto const accountReserve (mEngine->getLedger ()->getReserve (
47+
mTxnAccount->getFieldU32 (sfOwnerCount) + 1));
48+
49+
if (mPriorBalance.getNValue () < accountReserve)
50+
return tecINSUFFICIENT_RESERVE;
51+
52+
std::uint32_t expiration (0);
53+
54+
if (mTxn.isFieldPresent (sfExpiration))
55+
{
56+
expiration = mTxn.getFieldU32 (sfExpiration);
57+
58+
if (!expiration)
59+
{
60+
m_journal.warning <<
61+
"Malformed ticket requestion: bad expiration";
62+
63+
return temBAD_EXPIRATION;
64+
}
65+
66+
if (mEngine->getLedger ()->getParentCloseTimeNC () >= expiration)
67+
return tesSUCCESS;
68+
}
69+
70+
SLE::pointer sleTicket = mEngine->entryCreate (ltTICKET,
71+
Ledger::getTicketIndex (mTxnAccountID, mTxn.getSequence ()));
72+
73+
sleTicket->setFieldAccount (sfAccount, mTxnAccountID);
74+
sleTicket->setFieldU32 (sfSequence, mTxn.getSequence ());
75+
76+
if (expiration != 0)
77+
sleTicket->setFieldU32 (sfExpiration, expiration);
78+
79+
if (mTxn.isFieldPresent (sfTarget))
80+
{
81+
Account const target_account (mTxn.getFieldAccount160 (sfTarget));
82+
83+
SLE::pointer sleTarget = mEngine->entryCache (ltACCOUNT_ROOT,
84+
Ledger::getAccountRootIndex (target_account));
85+
86+
// Destination account does not exist.
87+
if (!sleTarget)
88+
return tecNO_TARGET;
89+
90+
// The issuing account is the default account to which the ticket
91+
// applies so don't bother saving it if that's what's specified.
92+
if (target_account != mTxnAccountID)
93+
sleTicket->setFieldAccount (sfTarget, target_account);
94+
}
95+
96+
std::uint64_t hint;
97+
98+
TER result = mEngine->view ().dirAdd (hint,
99+
Ledger::getOwnerDirIndex (mTxnAccountID), sleTicket->getIndex (),
100+
std::bind (&Ledger::ownerDirDescriber,
101+
std::placeholders::_1, std::placeholders::_2,
102+
mTxnAccountID));
103+
104+
m_journal.trace <<
105+
"Creating ticket " << to_string (sleTicket->getIndex ()) <<
106+
": " << transHuman (result);
107+
108+
if (result != tesSUCCESS)
109+
return result;
110+
111+
sleTicket->setFieldU64(sfOwnerNode, hint);
112+
113+
// If we succeeded, the new entry counts agains the creator's reserve.
114+
mEngine->view ().ownerCountAdjust (mTxnAccountID, 1, mTxnAccount);
115+
116+
return result;
117+
}
118+
};
119+
120+
TER
121+
transact_CreateTicket (
122+
SerializedTransaction const& txn,
123+
TransactionEngineParams params,
124+
TransactionEngine* engine)
125+
{
126+
return CreateTicket (txn, params, engine).apply ();
127+
}
128+
129+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2014 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+
#ifndef RIPPLE_TX_CREATETICKET_H_INCLUDED
21+
#define RIPPLE_TX_CREATETICKET_H_INCLUDED
22+
23+
namespace ripple {
24+
25+
}
26+
27+
#endif

src/ripple/module/app/transactors/Transactor.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ TER transact_CreateOffer (SerializedTransaction const& txn, TransactionEnginePar
2929
TER transact_CancelOffer (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
3030
TER transact_AddWallet (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
3131
TER transact_Change (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
32+
TER transact_CreateTicket (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
33+
TER transact_CancelTicket (SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine);
3234

3335
TER
3436
Transactor::transact (
@@ -63,6 +65,12 @@ Transactor::transact (
6365
case ttFEE:
6466
return transact_Change (txn, params, engine);
6567

68+
case ttTICKET_CREATE:
69+
return transact_CreateTicket (txn, params, engine);
70+
71+
case ttTICKET_CANCEL:
72+
return transact_CancelTicket (txn, params, engine);
73+
6674
default:
6775
return temUNKNOWN;
6876
}

src/ripple/module/data/protocol/LedgerFormats.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ LedgerFormats::LedgerFormats ()
100100
<< SOElement (sfReserveBase, SOE_REQUIRED)
101101
<< SOElement (sfReserveIncrement, SOE_REQUIRED)
102102
;
103+
104+
add ("Ticket", ltTICKET)
105+
<< SOElement (sfAccount, SOE_REQUIRED)
106+
<< SOElement (sfSequence, SOE_REQUIRED)
107+
<< SOElement (sfOwnerNode, SOE_REQUIRED)
108+
<< SOElement (sfTarget, SOE_OPTIONAL)
109+
<< SOElement (sfExpiration, SOE_OPTIONAL)
110+
;
103111
}
104112

105113
void LedgerFormats::addCommonFields (Item& item)

0 commit comments

Comments
 (0)