Open scottschurr opened 3 months ago
Attention: Patch coverage is 88.96714%
with 94 lines
in your changes are missing coverage. Please review.
Project coverage is 77.04%. Comparing base (
c28e005
) to head (eeb1098
). Report is 8 commits behind head on develop.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Why do you use the custom transaction method instead of doing this automatically which is what happens in activateTrustLinesToSelfFix
which is called when the amendment is activated? Are you worried that more corrupted pages will create before the amendment activates?
@exunda asked:
Why do you use the custom transaction method instead of doing this automatically which is what happens in activateTrustLinesToSelfFix which is called when the amendment is activated?
That's a fair question. It was answered in the (admittedly long) description of the pull request. Here's the quote:
We could put in code that cleans up the two known corrupted directories when the amendment goes live. That's not a good approach for two reasons:
- As mentioned before, additional directories could face similar corruption between now and when the amendment goes live. We would like to be able to clean up all damaged NFToken directories, regardless of when they are created.
- The MainNet is not the only place running the XRP Ledger code. Other networks may have similar corruptions that need to be fixed. The approach to the fix should be applicable to other networks as well.
We need a transaction to clean up the directories. There are no transactions that just naturally walk an NFToken directory. So we can't leverage an existing transaction. There are RPC commands that walk the directory, but RPC commands can't modify ledger state.
Does that answer your question?
Yes thank you for explaining more
High Level Overview of Change
It was discovered that there are a couple of NFT directories on the MainNet that are missing links in the middle of the chain. This pull request does several things to address the corruption:
LedgerStateFix
, is added which allows any account on ledger to pay the fee to repair the links of any single account.A new amendment,
fixNFTokenPageLinks
, includes all of these changes.Details follow.
The Source of the Corruption
There are two different transactions that introduced the corruption into the two directories. In both cases the following conditions were met:
When these conditions were met, the last NFToken page was removed and the next-to-last page was left as the final page in the directory.
That would be fine except the NFToken directory has a an expectation that the last page has a specific index. The page with that index was just deleted. So when an NFToken is added to the directory, and that token has a high enough value that it does not belong on the new last page, then a new last page is created that has no links to the previous page.
Now there's a linked list with a hole in the middle of the list.
The
fixNFTokenPageLinks
amendment modifies the NFToken page coalescing code to notice when the very last page of the directory would be removed. In that case it simply moves all of the contents of the next lower page into the last page and deletes the next-to-last page (and fixes up the links).New invariant checks also validate aspects of the links on pages, so a similar corruption should cause a
tecINVARIANT_FAILED
transaction result. That should prevent similar corruptions in the future.The New Transaction:
LedgerStateFix
Once the amendment goes live then that prevents any similar NFToken directory corruption in the future. But we are still left with two damaged NFToken directories. And potentially more that could be created between now and when the amendment goes live.
We could leave the corruptions. I don't like that idea for two reasons:
We could put in code that cleans up the two known corrupted directories when the amendment goes live. That's not a good approach for two reasons:
We need a transaction to clean up the directories. There are no transactions that just naturally walk an NFToken directory. So we can't leverage an existing transaction. There are RPC commands that walk the directory, but RPC commands can't modify ledger state.
But we would also rather not introduce a new single-use transaction for this very tiny corner case.
So this approach creates a new transaction aimed at cleaning up messes in the ledger:
LedgerStateFix
. We'll use it for this situation. If there are other repairable corruptions in the future we can re-use this transaction to repair those future corruptions.LedgerStateFix
LedgerStateFix
fields (in addition to common fields) are:TransactionType
uint16
LedgerStateFix
Account
STAccount
Fee
STAmount
Flags
uint32
LedgerFixType
uint16
1
is currently supportedOwner
STAccount
LedgerFixType
==1
TransactionType
— identifies this as aLedgerStateFix
transaction.Account
— identifies the account signing and submitting the transaction as well as paying theFee
.Fee
— this transaction is rare and potentially compute intensive. We want to discourage folks from spamming the ledger with these. So the minimum fee is the same as the fee for anAccountDelete
transaction. And, yes, if the transaction fails with atec
code the fee is still charged.Flags
— not needed forLedgerFixType == 1
. May be used for some unknown future ledger fix.LedgerFixType
— for now the only valid value is1
, which fixes the NFToken directory for a single account.Owner
— the account that owns the NFToken directory that needs fixing. Need not have any relationship toAccount
.Fixing NFTokenPage Links
Once the amendment goes live, any corrupted NFTokenPage directory can be fixed by submitting a transaction like this:
If a repair is actually completed, then
tesSUCCESS
is returned. If there is an error or if the directory did not need repair then atec
code is returned.Future Fixes
Unfortunately this is not the first time ledger state has needed tidying up. Amendment
fixTrustLinesToSelf
removed invalid state from the ledger. Since programmers are humans we can expect similar kinds of problems to show up in the future.If there are future ledger state problems, they can be attached to the
LedgerStateFix
transaction by picking aLedgerFixType
value other than1
. Any additional parameters can be added as optional values.Context of Change
While I was research how efficient NFTokenPages actually are in use, I stumbled across two NFToken directories that were missing links in the middle of the chain. This is a form of ledger corruption. But its consequences do not seem too dire, even for the owners of those directories. Known consequences are:
account_objects
RPC command returns only those objects at the beginning of the NFToken directory up to the point where a link is missing. So, for those accounts with missing links, the NFTokens returned byaccount_objects
is incomplete.account_nfts
RPC command has a problem similar toaccount_objects
.account_nfts
returns NFTokens only up to the point where a link is missing.There may be other consequences, but I've looked for and not found any. Particularly, I've not seen any evidence of lost NFTokens. NFTokens still get added to the correct owner's page. They simply are not reported by the RPC commands.
Type of Change
API Impact
Consideration
This NFT-related amendment arrives at about the same time as a different NFT-related amendment: https://github.com/XRPLF/rippled/pull/4946
Should these two pull requests be merged into a single amendment?