Introduce shadow tickets for export replay protection:
- ltSHADOW_TICKET ledger entry: account-owned, keyed by
account + ticket sequence. Fields: sfAccount, sfTicketSequence,
sfTransactionHash, sfLedgerSequence, sfOwnerNode.
- ExportLedgerOps::createShadowTicket(): creates shadow ticket
when exported tx has sfTicketSequence. Charges owner reserve.
Called from both hook xport() path and Export transactor.
- ExportLedgerOps::cancelShadowTicket(): deletes shadow ticket,
frees reserve. Used by xport_cancel hook API.
- xport_cancel(ticket_seq) hook API: allows hooks to cancel
shadow tickets for exports that will never get a callback.
- InvariantCheck: add ltSHADOW_TICKET to valid entry types.
- Test: verify shadow ticket creation with correct fields and
owner count bump via ttEXPORT with TicketSequence.
Both xrpld.overlay and xrpl.hook depend on xrpl.protocol, so placing
the header there avoids introducing a new xrpld.overlay > xrpl.hook
levelization dependency.
- max_export per hook: 4 → 2
- maxPendingExports: cap exported directory at 8 entries (tecDIR_FULL)
- clamp inbound signature processing in PeerImp to directory cap
The directory cap is the root DoS constraint: each pending export
requires every validator to sign and broadcast every round. Inbound
processing and signing throughput are transitively bounded by it.
Resolve the origin/dev post-2.4.0 sync conflicts across the xrpld path migration and macro-based protocol registration changes.
Re-apply export/RNG integration on top of the new structure, including consensus/build plumbing, tx/apply paths, peer ingest, and tests.
Regenerate hook headers and restore a green build via x-run-tests (Export_test build path).