mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add ledger support for directories and ripple state.
This commit is contained in:
54
src/Ledger.h
54
src/Ledger.h
@@ -18,17 +18,17 @@
|
||||
|
||||
enum LedgerStateParms
|
||||
{
|
||||
lepNONE = 0, // no special flags
|
||||
lepNONE = 0, // no special flags
|
||||
|
||||
// input flags
|
||||
lepCREATE = 1, // Create if not present
|
||||
lepCREATE = 1, // Create if not present
|
||||
|
||||
// output flags
|
||||
lepOKAY = 2, // success
|
||||
lepMISSING = 4, // No node in that slot
|
||||
lepWRONGTYPE = 8, // Node of different type there
|
||||
lepCREATED = 16, // Node was created
|
||||
lepERROR = 32, // error
|
||||
lepOKAY = 2, // success
|
||||
lepMISSING = 4, // No node in that slot
|
||||
lepWRONGTYPE = 8, // Node of different type there
|
||||
lepCREATED = 16, // Node was created
|
||||
lepERROR = 32, // error
|
||||
};
|
||||
|
||||
class Ledger : public boost::enable_shared_from_this<Ledger>
|
||||
@@ -132,8 +132,6 @@ public:
|
||||
SerializedLedgerEntry::pointer getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID);
|
||||
SerializedLedgerEntry::pointer getNickname(LedgerStateParms& parms, const std::string& nickname);
|
||||
SerializedLedgerEntry::pointer getNickname(LedgerStateParms& parms, const uint256& nickHash);
|
||||
// SerializedLedgerEntry::pointer getRippleState(LedgerStateParms parms, const uint160& offeror,
|
||||
// const uint160& borrower, const Currency& currency);
|
||||
|
||||
// database functions
|
||||
static void saveAcceptedLedger(Ledger::pointer);
|
||||
@@ -142,7 +140,7 @@ public:
|
||||
|
||||
// index calculation functions
|
||||
static uint256 getAccountRootIndex(const uint160& account)
|
||||
{ return uint160extend256(account, 0); } // Index is accountID extended to 256 bits
|
||||
{ return uint160extend256(account, lnsAccounts); } // Index is accountID extended to 256 bits
|
||||
|
||||
static uint256 getAccountRootIndex(const NewcoinAddress& account)
|
||||
{ return getAccountRootIndex(account.getAccountID()); }
|
||||
@@ -154,28 +152,48 @@ public:
|
||||
SerializedLedgerEntry::pointer getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID);
|
||||
|
||||
static uint256 getGeneratorIndex(const uint160& uGeneratorID)
|
||||
{ return uint160extend256(uGeneratorID, 1); } // Index is the generator ID extended to 256 bits in namespace 1
|
||||
{ return uint160extend256(uGeneratorID, lnsGenerator); } // Index is the generator ID extended to 256 bits in namespace 1
|
||||
|
||||
//
|
||||
// Ripple functions
|
||||
//
|
||||
|
||||
static uint256 getRippleIndex(const uint160& account, const uint160& extendTo, const uint160& currency);
|
||||
static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency);
|
||||
static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
|
||||
{ return getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency); }
|
||||
|
||||
static uint256 getRippleIndex(const uint160& account, const uint160& extendTo)
|
||||
{ return getRippleIndex(account, extendTo, uint160()); }
|
||||
|
||||
static uint256 getRippleIndex(const NewcoinAddress& account, const NewcoinAddress& extendTo,
|
||||
const uint160& currency)
|
||||
{ return getRippleIndex(account.getAccountID(), extendTo.getAccountID(), currency); }
|
||||
static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB)
|
||||
{ return getRippleStateIndex(naA, naB, uint160()); }
|
||||
|
||||
static uint160 getOfferBase(const uint160& currencyIn, const uint160& accountIn,
|
||||
const uint160& currencyOut, const uint160& accountOut);
|
||||
|
||||
//
|
||||
// Offer functions
|
||||
//
|
||||
|
||||
static uint256 getOfferIndex(const uint160& offerBase, uint64 rate, int skip = 0);
|
||||
|
||||
static int getOfferSkip(const uint256& offerId);
|
||||
|
||||
SerializedLedgerEntry::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency);
|
||||
SerializedLedgerEntry::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
|
||||
{
|
||||
return getRippleState(parms, NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency);
|
||||
}
|
||||
|
||||
//
|
||||
// Directory functions
|
||||
//
|
||||
|
||||
static uint256 getDirIndex(const uint256& uBase, const LedgerEntryType letKind, const uint64 uNodeDir=0);
|
||||
|
||||
SerializedLedgerEntry::pointer getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex);
|
||||
SerializedLedgerEntry::pointer getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex);
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
bool isCompatible(boost::shared_ptr<Ledger> other);
|
||||
// bool signLedger(std::vector<unsigned char> &signature, const LocalHanko &hanko);
|
||||
|
||||
|
||||
@@ -17,42 +17,48 @@ LedgerEntryFormat LedgerFormats[]=
|
||||
{ S_FIELD(WalletLocator), STI_HASH256, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(TransitRate), STI_UINT32, SOE_IFFLAG, 16 },
|
||||
{ S_FIELD(TransitExpire), STI_UINT32, SOE_IFFLAG, 32 },
|
||||
{ S_FIELD(NextTransitRate), STI_UINT32, SOE_IFFLAG, 64 },
|
||||
{ S_FIELD(NextTransitStart), STI_UINT32, SOE_IFFLAG, 128 },
|
||||
{ S_FIELD(NextTransitExpire), STI_UINT32, SOE_IFFLAG, 256 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "DirectoryRoot", ltDIR_ROOT, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(FirstNode), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LastNode), STI_UINT64, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "DirectoryNode", ltDIR_NODE, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Indexes), STI_VECTOR256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "GeneratorMap", ltGENERATOR_MAP, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(GeneratorID), STI_HASH160, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(GeneratorID), STI_HASH160, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "Nickname", ltNICKNAME, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(OfferCurrency),STI_HASH160, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(OfferCurrency), STI_HASH160, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ "RippleState", ltRIPPLE_STATE, {
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Borrower), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Lender), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Limit), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(CurrentRate), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(RateLock), STI_UINT32, SOE_IFFLAG, 2 },
|
||||
{ S_FIELD(NextRate), STI_UINT32, SOE_IFFLAG, 4 },
|
||||
{ S_FIELD(NextRateLgr), STI_UINT32, SOE_IFFLAG, 8 },
|
||||
{ S_FIELD(NextRateExp), STI_UINT32, SOE_IFFLAG, 16 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||
{ S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LowID), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(LowLimit), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(HighID), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(HighLimit), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||
{ S_FIELD(AcceptRate), STI_UINT32, SOE_IFFLAG, 1 },
|
||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||
},
|
||||
{ NULL, ltINVALID }
|
||||
};
|
||||
|
||||
@@ -5,18 +5,37 @@
|
||||
|
||||
enum LedgerEntryType
|
||||
{
|
||||
ltINVALID =-1,
|
||||
ltACCOUNT_ROOT =0,
|
||||
ltRIPPLE_STATE =1,
|
||||
ltGENERATOR_MAP =2,
|
||||
ltNICKNAME =3
|
||||
ltINVALID = -1,
|
||||
ltACCOUNT_ROOT,
|
||||
ltDIR_ROOT,
|
||||
ltDIR_NODE,
|
||||
ltGENERATOR_MAP,
|
||||
ltRIPPLE_STATE,
|
||||
ltNICKNAME
|
||||
};
|
||||
|
||||
// In the format 160 + namespace + other.
|
||||
enum LedgerNameSpace
|
||||
{
|
||||
lnsGenerator = -1,
|
||||
lnsAccounts,
|
||||
lnsRipple,
|
||||
lnsBonds,
|
||||
lnsInvoices,
|
||||
lnsMultiSig
|
||||
};
|
||||
|
||||
enum LedgerSpecificFlags
|
||||
{
|
||||
lsfLowIndexed = 0x00010000,
|
||||
lsfHighIndexed = 0x00020000,
|
||||
};
|
||||
|
||||
struct LedgerEntryFormat
|
||||
{
|
||||
const char *t_name;
|
||||
LedgerEntryType t_type;
|
||||
SOElement elements[16];
|
||||
SOElement elements[20];
|
||||
};
|
||||
|
||||
extern LedgerEntryFormat LedgerFormats[];
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
|
||||
#include "Ledger.h"
|
||||
|
||||
uint256 Ledger::getRippleIndex(const uint160& accountID, const uint160& extendTo, const uint160& currency)
|
||||
{ // Index is 160-bit account credit extended to, 96-bit XOR of extending account and currency
|
||||
uint256 base = getAccountRootIndex(extendTo);
|
||||
memcpy(base.begin() + (160 / 8), (accountID ^ currency).begin(), (256 / 8) - (160 / 8));
|
||||
return base;
|
||||
uint256 Ledger::getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency)
|
||||
{
|
||||
uint160 uAID = naA.getAccountID();
|
||||
uint160 uBID = naB.getAccountID();
|
||||
bool bAltB = uAID < uBID;
|
||||
Serializer s;
|
||||
|
||||
s.add160(bAltB ? uAID : uBID);
|
||||
s.add160(bAltB ? uBID : uAID);
|
||||
s.add160(uCurrency);
|
||||
|
||||
return s.getSHA512Half();
|
||||
}
|
||||
|
||||
uint160 Ledger::getOfferBase(const uint160& currencyIn, const uint160& accountIn,
|
||||
|
||||
@@ -137,4 +137,80 @@ SerializedLedgerEntry::pointer Ledger::getGenerator(LedgerStateParms& parms, con
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Ripple State
|
||||
//
|
||||
|
||||
SerializedLedgerEntry::pointer Ledger::getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency)
|
||||
{
|
||||
uint256 nodeID=getRippleStateIndex(naA, naB, uCurrency);
|
||||
|
||||
ScopedLock l(mAccountStateMap->Lock());
|
||||
|
||||
try
|
||||
{
|
||||
return getASNode(parms, nodeID, ltRIPPLE_STATE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
parms = lepERROR;
|
||||
return SerializedLedgerEntry::pointer();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Directory
|
||||
//
|
||||
|
||||
uint256 Ledger::getDirIndex(const uint256& uBase, const LedgerEntryType letKind, const uint64 uNodeDir)
|
||||
{
|
||||
// Indexes are stored in little endian format.
|
||||
// The low bytes are indexed first, so when printed as a hex stream the hex is in byte order.
|
||||
// Therefore, we place uNodeDir in the 8 right most bytes.
|
||||
Serializer sKey;
|
||||
|
||||
sKey.add256(uBase);
|
||||
sKey.add8(letKind);
|
||||
|
||||
uint256 uResult = sKey.getSHA512Half();
|
||||
|
||||
Serializer sNode; // Put in a fixed byte order: BIG. YYY
|
||||
|
||||
sNode.add64(uNodeDir);
|
||||
|
||||
std::copy(sNode.getData().end()-8, sNode.getData().end(), uResult.begin()+((256-64)/8));
|
||||
|
||||
return uResult;
|
||||
}
|
||||
|
||||
SerializedLedgerEntry::pointer Ledger::getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex)
|
||||
{
|
||||
ScopedLock l(mAccountStateMap->Lock());
|
||||
|
||||
try
|
||||
{
|
||||
return getASNode(parms, uRootIndex, ltDIR_ROOT);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
parms = lepERROR;
|
||||
return SerializedLedgerEntry::pointer();
|
||||
}
|
||||
}
|
||||
|
||||
SerializedLedgerEntry::pointer Ledger::getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex)
|
||||
{
|
||||
ScopedLock l(mAccountStateMap->Lock());
|
||||
|
||||
try
|
||||
{
|
||||
return getASNode(parms, uNodeIndex, ltDIR_NODE);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
parms = lepERROR;
|
||||
return SerializedLedgerEntry::pointer();
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -32,6 +32,10 @@ public:
|
||||
void add(Serializer& s) const { mVersion.add(s); mObject.add(s); }
|
||||
virtual bool isEquivalent(const SerializedType& t) const;
|
||||
|
||||
bool setFlag(uint32 uSet) { return mObject.setFlag(uSet); }
|
||||
bool clearFlag(uint32 uClear) { return mObject.clearFlag(uClear); }
|
||||
uint32 getFlags() const { return mObject.getFlags(); }
|
||||
|
||||
const uint256& getIndex() const { return mIndex; }
|
||||
void setIndex(const uint256& i) { mIndex = i; }
|
||||
|
||||
@@ -55,6 +59,8 @@ public:
|
||||
std::vector<TaggedListItem> getIFieldTL(SOE_Field field) const { return mObject.getValueFieldTL(field); }
|
||||
NewcoinAddress getIValueFieldAccount(SOE_Field field) const { return mObject.getValueFieldAccount(field); }
|
||||
STAmount getIValueFieldAmount(SOE_Field field) const { return mObject.getValueFieldAmount(field); }
|
||||
STVector256 getIFieldV256(SOE_Field field) { return mObject.getValueFieldV256(field); }
|
||||
|
||||
void setIFieldU8(SOE_Field field, unsigned char v) { return mObject.setValueFieldU8(field, v); }
|
||||
void setIFieldU16(SOE_Field field, uint16 v) { return mObject.setValueFieldU16(field, v); }
|
||||
void setIFieldU32(SOE_Field field, uint32 v) { return mObject.setValueFieldU32(field, v); }
|
||||
@@ -71,6 +77,7 @@ public:
|
||||
{ return mObject.setValueFieldAccount(field, account); }
|
||||
void setIFieldAmount(SOE_Field field, const STAmount& amount)
|
||||
{ return mObject.setValueFieldAmount(field, amount); }
|
||||
void setIFieldV256(SOE_Field field, const STVector256& v) { return mObject.setValueFieldV256(field, v); }
|
||||
|
||||
bool getIFieldPresent(SOE_Field field) const { return mObject.isFieldPresent(field); }
|
||||
void makeIFieldPresent(SOE_Field field) { mObject.makeFieldPresent(field); }
|
||||
|
||||
Reference in New Issue
Block a user