mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 03:26:01 +00:00
Metadata rework to make it possible to watch things like order books or
directories. 1) Some fields are never put in metadata, like Indexes, PreviousTxnID, and others that are useless/redundant 2) Directory nodes now contain a RootIndex field so you can tell which directory they're part of. 3) Some fields are always put in metdata, even if they don't change, like RootIndex. So if a directory entry node is touched, you can tell what directory it was part of. Note that this change will cause ledger divergence. Also, existing directory nodes will not be fully metadata indexed but newly-created nodes will be.
This commit is contained in:
@@ -28,8 +28,16 @@ SField sfIndex(STI_HASH256, 258, "index");
|
||||
|
||||
static int initFields()
|
||||
{
|
||||
sfTxnSignature.notSigningField(); sfTxnSignatures.notSigningField();
|
||||
sfTxnSignature.notSigningField();
|
||||
sfTxnSignatures.notSigningField();
|
||||
sfSignature.notSigningField();
|
||||
|
||||
sfIndexes.setMeta(SField::sMD_Never);
|
||||
sfPreviousTxnID.setMeta(SField::sMD_Never);
|
||||
sfPreviousTxnLgrSeq.setMeta(SField::sMD_Never);
|
||||
sfLedgerEntryType.setMeta(SField::sMD_Never);
|
||||
sfRootIndex.setMeta(SField::sMD_Always);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static const int f = initFields();
|
||||
|
||||
@@ -40,6 +40,14 @@ public:
|
||||
typedef const SField& ref;
|
||||
typedef SField const * ptr;
|
||||
|
||||
static const int sMD_Never = 0x00;
|
||||
static const int sMD_ChangeOrig = 0x01; // original value when it changes
|
||||
static const int sMD_ChangeNew = 0x02; // new value when it changes
|
||||
static const int sMD_DeleteFinal = 0x04; // final value when it is deleted
|
||||
static const int sMD_Create = 0x08; // value when it's created
|
||||
static const int sMD_Always = 0x10; // value when node containing it is affected at all
|
||||
static const int sMD_Default = sMD_ChangeOrig | sMD_ChangeNew | sMD_DeleteFinal;
|
||||
|
||||
protected:
|
||||
static std::map<int, ptr> codeToField;
|
||||
static boost::mutex mapMutex;
|
||||
@@ -52,23 +60,25 @@ public:
|
||||
const SerializedTypeID fieldType; // STI_*
|
||||
const int fieldValue; // Code number for protocol
|
||||
std::string fieldName;
|
||||
int fieldMeta;
|
||||
bool signingField;
|
||||
|
||||
SField(int fc, SerializedTypeID tid, int fv, const char* fn) :
|
||||
fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn), signingField(true)
|
||||
fieldCode(fc), fieldType(tid), fieldValue(fv), fieldName(fn), fieldMeta(sMD_Default), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
codeToField[fieldCode] = this;
|
||||
}
|
||||
|
||||
SField(SerializedTypeID tid, int fv, const char *fn) :
|
||||
fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn), signingField(true)
|
||||
fieldCode(FIELD_CODE(tid, fv)), fieldType(tid), fieldValue(fv), fieldName(fn),
|
||||
fieldMeta(sMD_Default), signingField(true)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mapMutex);
|
||||
codeToField[fieldCode] = this;
|
||||
}
|
||||
|
||||
SField(int fc) : fieldCode(fc), fieldType(STI_UNKNOWN), fieldValue(0) { ; }
|
||||
SField(int fc) : fieldCode(fc), fieldType(STI_UNKNOWN), fieldValue(0), fieldMeta(sMD_Never) { ; }
|
||||
|
||||
~SField();
|
||||
|
||||
@@ -88,6 +98,8 @@ public:
|
||||
|
||||
bool isSigningField() const { return signingField; }
|
||||
void notSigningField() { signingField = false; }
|
||||
bool shouldMeta(int c) const { return (fieldMeta & c) != 0; }
|
||||
void setMeta(int c) { fieldMeta = c; }
|
||||
|
||||
bool shouldInclude(bool withSigningField) const
|
||||
{ return (fieldValue < 256) && (withSigningField || signingField); }
|
||||
|
||||
@@ -407,59 +407,66 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
|
||||
mSet.setAffectedNode(it.first, *type, nodeType);
|
||||
|
||||
if (type == &sfDeletedNode)
|
||||
{
|
||||
{ // nodes was deleted
|
||||
assert(origNode);
|
||||
assert(curNode);
|
||||
threadOwners(origNode, mLedger, newMod);
|
||||
threadOwners(origNode, mLedger, newMod); // thread transaction to owners
|
||||
|
||||
STObject mods(sfPreviousFields);
|
||||
STObject finals(sfFinalFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *curNode)
|
||||
{ // save non-default values
|
||||
if (!obj.isDefault() && (obj.getFName() != sfLedgerEntryType))
|
||||
finals.addObject(obj);
|
||||
}
|
||||
if (!finals.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(finals);
|
||||
}
|
||||
|
||||
if ((type == &sfDeletedNode || type == &sfModifiedNode))
|
||||
{
|
||||
STObject mods(sfPreviousFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *origNode)
|
||||
{ // search the original node for values saved on modify
|
||||
if (!obj.isDefault() && (obj.getFName() != sfLedgerEntryType) && !curNode->hasMatchingEntry(obj))
|
||||
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
|
||||
mods.addObject(obj);
|
||||
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_DeleteFinal))
|
||||
finals.addObject(obj);
|
||||
}
|
||||
if (!mods.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(mods);
|
||||
if (!finals.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(finals);
|
||||
}
|
||||
else if (type == &sfModifiedNode)
|
||||
{
|
||||
if (curNode->isThreadedType()) // thread transaction to node it modified
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
|
||||
if (type == &sfCreatedNode) // if created, thread to owner(s)
|
||||
STObject mods(sfPreviousFields);
|
||||
STObject finals(sfFinalFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *origNode)
|
||||
{ // search the original node for values saved on modify
|
||||
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
|
||||
mods.addObject(obj);
|
||||
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_ChangeNew))
|
||||
finals.addObject(obj);
|
||||
}
|
||||
if (!mods.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(mods);
|
||||
if (!finals.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(finals);
|
||||
}
|
||||
else if (type == &sfCreatedNode) // if created, thread to owner(s)
|
||||
{
|
||||
assert(!origNode);
|
||||
threadOwners(curNode, mLedger, newMod);
|
||||
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
STObject news(sfNewFields);
|
||||
BOOST_FOREACH(const SerializedType& obj, *curNode)
|
||||
{ // save non-default values
|
||||
if (!obj.isDefault() && (obj.getFName() != sfLedgerEntryType))
|
||||
if (!obj.isDefault() && obj.getFName().shouldMeta(SField::sMD_Create | SField::sMD_Always))
|
||||
news.addObject(obj);
|
||||
}
|
||||
if (!news.empty())
|
||||
mSet.getAffectedNode(it.first, *type).addObject(news);
|
||||
}
|
||||
|
||||
if ((type == &sfCreatedNode) || (type == &sfModifiedNode))
|
||||
{
|
||||
if (curNode->isThreadedType()) // always thread to self
|
||||
threadTx(curNode, mLedger, newMod);
|
||||
}
|
||||
}
|
||||
|
||||
// add any new modified nodes to the modification set
|
||||
for (boost::unordered_map<uint256, SLE::pointer>::iterator it = newMod.begin(), end = newMod.end();
|
||||
it != end; ++it)
|
||||
entryModify(it->second);
|
||||
typedef std::pair<const uint256, SLE::pointer> u256_sle_pair;
|
||||
BOOST_FOREACH(u256_sle_pair& it, newMod)
|
||||
entryModify(it.second);
|
||||
|
||||
mSet.addRaw(s, result);
|
||||
cLog(lsTRACE) << "Metadata:" << mSet.getJson(0);
|
||||
@@ -483,6 +490,7 @@ TER LedgerEntrySet::dirAdd(
|
||||
{
|
||||
// No root, make it.
|
||||
sleRoot = entryCreate(ltDIR_NODE, uRootIndex);
|
||||
sleRoot->setFieldH256(sfRootIndex, uRootIndex);
|
||||
|
||||
sleNode = sleRoot;
|
||||
uNodeDir = 0;
|
||||
@@ -543,6 +551,7 @@ TER LedgerEntrySet::dirAdd(
|
||||
|
||||
// Create the new node.
|
||||
sleNode = entryCreate(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
|
||||
sleNode->setFieldH256(sfRootIndex, uRootIndex);
|
||||
svIndexes = STVector256();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ static bool LEFInit()
|
||||
|
||||
DECLARE_LEF(DirectoryNode, ltDIR_NODE)
|
||||
<< SOElement(sfIndexes, SOE_REQUIRED)
|
||||
<< SOElement(sfRootIndex, SOE_REQUIRED)
|
||||
<< SOElement(sfIndexNext, SOE_OPTIONAL)
|
||||
<< SOElement(sfIndexPrevious, SOE_OPTIONAL)
|
||||
;
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
FIELD(PreviousTxnID, HASH256, 5)
|
||||
FIELD(LedgerIndex, HASH256, 6)
|
||||
FIELD(WalletLocator, HASH256, 7)
|
||||
FIELD(RootIndex, HASH256, 8)
|
||||
|
||||
// 256-bit (uncommon)
|
||||
FIELD(BookDirectory, HASH256, 16)
|
||||
|
||||
Reference in New Issue
Block a user