From e16f82465815c47c83ec3f29561c1cab99eac6dc Mon Sep 17 00:00:00 2001 From: Garand Tyson Date: Wed, 14 Aug 2024 09:58:39 -0700 Subject: [PATCH] Archival proofs (#204) (#205) * Added Archival proof types * Moved Bucket types to remove circular dependency --- Stellar-ledger-entries.x | 116 +++++++++++++++++++++++++++++++++++++++ Stellar-ledger.x | 68 ----------------------- Stellar-transaction.x | 54 +++++++++++++++++- 3 files changed, 169 insertions(+), 69 deletions(-) diff --git a/Stellar-ledger-entries.x b/Stellar-ledger-entries.x index 3a137ae..44d06c0 100644 --- a/Stellar-ledger-entries.x +++ b/Stellar-ledger-entries.x @@ -679,3 +679,119 @@ enum EnvelopeType ENVELOPE_TYPE_SOROBAN_AUTHORIZATION = 9 }; } + +enum BucketListType +{ + LIVE = 0, + HOT_ARCHIVE = 1, + COLD_ARCHIVE = 2 +}; + +/* Entries used to define the bucket list */ +enum BucketEntryType +{ + METAENTRY = + -1, // At-and-after protocol 11: bucket metadata, should come first. + LIVEENTRY = 0, // Before protocol 11: created-or-updated; + // At-and-after protocol 11: only updated. + DEADENTRY = 1, + INITENTRY = 2 // At-and-after protocol 11: only created. +}; + +enum HotArchiveBucketEntryType +{ + HOT_ARCHIVE_METAENTRY = -1, // Bucket metadata, should come first. + HOT_ARCHIVE_ARCHIVED = 0, // Entry is Archived + HOT_ARCHIVE_LIVE = 1, // Entry was previously HOT_ARCHIVE_ARCHIVED, or HOT_ARCHIVE_DELETED, but + // has been added back to the live BucketList. + // Does not need to be persisted. + HOT_ARCHIVE_DELETED = 2 // Entry deleted (Note: must be persisted in archive) +}; + +enum ColdArchiveBucketEntryType +{ + COLD_ARCHIVE_METAENTRY = -1, // Bucket metadata, should come first. + COLD_ARCHIVE_ARCHIVED_LEAF = 0, // Full LedgerEntry that was archived during the epoch + COLD_ARCHIVE_DELETED_LEAF = 1, // LedgerKey that was deleted during the epoch + COLD_ARCHIVE_BOUNDARY_LEAF = 2, // Dummy leaf representing low/high bound + COLD_ARCHIVE_HASH = 3 // Intermediary Merkle hash entry +}; + +struct BucketMetadata +{ + // Indicates the protocol version used to create / merge this bucket. + uint32 ledgerVersion; + + // reserved for future use + union switch (int v) + { + case 0: + void; + case 1: + BucketListType bucketListType; + } + ext; +}; + +union BucketEntry switch (BucketEntryType type) +{ +case LIVEENTRY: +case INITENTRY: + LedgerEntry liveEntry; + +case DEADENTRY: + LedgerKey deadEntry; +case METAENTRY: + BucketMetadata metaEntry; +}; + +union HotArchiveBucketEntry switch (HotArchiveBucketEntryType type) +{ +case HOT_ARCHIVE_ARCHIVED: + LedgerEntry archivedEntry; + +case HOT_ARCHIVE_LIVE: +case HOT_ARCHIVE_DELETED: + LedgerKey key; +case HOT_ARCHIVE_METAENTRY: + BucketMetadata metaEntry; +}; + +struct ColdArchiveArchivedLeaf +{ + uint32 index; + LedgerEntry archivedEntry; +}; + +struct ColdArchiveDeletedLeaf +{ + uint32 index; + LedgerKey deletedKey; +}; + +struct ColdArchiveBoundaryLeaf +{ + uint32 index; + bool isLowerBound; +}; + +struct ColdArchiveHashEntry +{ + uint32 index; + uint32 level; + Hash hash; +}; + +union ColdArchiveBucketEntry switch (ColdArchiveBucketEntryType type) +{ +case COLD_ARCHIVE_METAENTRY: + BucketMetadata metaEntry; +case COLD_ARCHIVE_ARCHIVED_LEAF: + ColdArchiveArchivedLeaf archivedLeaf; +case COLD_ARCHIVE_DELETED_LEAF: + ColdArchiveDeletedLeaf deletedLeaf; +case COLD_ARCHIVE_BOUNDARY_LEAF: + ColdArchiveBoundaryLeaf boundaryLeaf; +case COLD_ARCHIVE_HASH: + ColdArchiveHashEntry hashEntry; +}; diff --git a/Stellar-ledger.x b/Stellar-ledger.x index c71e8b5..9c0d036 100644 --- a/Stellar-ledger.x +++ b/Stellar-ledger.x @@ -157,74 +157,6 @@ struct ConfigUpgradeSet { ConfigSettingEntry updatedEntry<>; }; -enum BucketListType -{ - LIVE = 0, - HOT_ARCHIVE = 1, - COLD_ARCHIVE = 2 -}; - -/* Entries used to define the bucket list */ -enum BucketEntryType -{ - METAENTRY = - -1, // At-and-after protocol 11: bucket metadata, should come first. - LIVEENTRY = 0, // Before protocol 11: created-or-updated; - // At-and-after protocol 11: only updated. - DEADENTRY = 1, - INITENTRY = 2 // At-and-after protocol 11: only created. -}; - -enum HotArchiveBucketEntryType -{ - HOT_ARCHIVE_METAENTRY = -1, // Bucket metadata, should come first. - HOT_ARCHIVE_ARCHIVED = 0, // Entry is Archived - HOT_ARCHIVE_LIVE = 1, // Entry was previously HOT_ARCHIVE_ARCHIVED, or HOT_ARCHIVE_DELETED, but - // has been added back to the live BucketList. - // Does not need to be persisted. - HOT_ARCHIVE_DELETED = 2 // Entry deleted (Note: must be persisted in archive) -}; - -struct BucketMetadata -{ - // Indicates the protocol version used to create / merge this bucket. - uint32 ledgerVersion; - - // reserved for future use - union switch (int v) - { - case 0: - void; - case 1: - BucketListType bucketListType; - } - ext; -}; - -union BucketEntry switch (BucketEntryType type) -{ -case LIVEENTRY: -case INITENTRY: - LedgerEntry liveEntry; - -case DEADENTRY: - LedgerKey deadEntry; -case METAENTRY: - BucketMetadata metaEntry; -}; - -union HotArchiveBucketEntry switch (HotArchiveBucketEntryType type) -{ -case HOT_ARCHIVE_ARCHIVED: - LedgerEntry archivedEntry; - -case HOT_ARCHIVE_LIVE: -case HOT_ARCHIVE_DELETED: - LedgerKey key; -case HOT_ARCHIVE_METAENTRY: - BucketMetadata metaEntry; -}; - enum TxSetComponentType { // txs with effective fee <= bid derived from a base fee (if any). diff --git a/Stellar-transaction.x b/Stellar-transaction.x index 8668249..f9b63f6 100644 --- a/Stellar-transaction.x +++ b/Stellar-transaction.x @@ -819,6 +819,52 @@ struct LedgerFootprint LedgerKey readWrite<>; }; +enum ArchivalProofType +{ + EXISTENCE = 0, + NONEXISTENCE = 1 +}; + +struct ArchivalProofNode +{ + uint32 index; + Hash hash; +}; + +typedef ArchivalProofNode ProofLevel<>; + +struct ArchivalProof +{ + uint32 epoch; // AST Subtree for this proof + + union switch (ArchivalProofType t) + { + case EXISTENCE: + struct + { + ColdArchiveBucketEntry entriesToProve<>; + + // Vector of vectors, where proofLevels[level] + // contains all HashNodes that correspond with that level + ProofLevel proofLevels<>; + } existenceProof; + case NONEXISTENCE: + struct + { + LedgerKey keysToProve<>; + + // Bounds for each key being proved, where bound[n] + // corresponds to keysToProve[n] + ColdArchiveBucketEntry lowBoundEntries<>; + ColdArchiveBucketEntry highBoundEntries<>; + + // Vector of vectors, where proofLevels[level] + // contains all HashNodes that correspond with that level + ProofLevel proofLevels<>; + } nonexistenceProof; + } type; +}; + // Resource limits for a Soroban transaction. // The transaction will fail if it exceeds any of these limits. struct SorobanResources @@ -837,7 +883,13 @@ struct SorobanResources // The transaction extension for Soroban. struct SorobanTransactionData { - ExtensionPoint ext; + union switch (int v) + { + case 0: + void; + case 1: + ArchivalProof proofs<>; + } ext; SorobanResources resources; // Amount of the transaction `fee` allocated to the Soroban resource fees. // The fraction of `resourceFee` corresponding to `resources` specified