|
26 | 26 |
|
27 | 27 | namespace stellar
|
28 | 28 | {
|
29 |
| - |
| 29 | +namespace |
| 30 | +{ |
| 31 | +void |
| 32 | +enforcePreLoadInvariants(LedgerKey const& key, uint32_t ledgerVersion) |
| 33 | +{ |
| 34 | + switch (key.type()) |
| 35 | + { |
| 36 | + case ACCOUNT: |
| 37 | + break; |
| 38 | + case DATA: |
| 39 | + break; |
| 40 | + case OFFER: |
| 41 | + // Ensure offer is not XLM -- possibly? |
| 42 | + // special case for offer loading from allow trust op frame? |
| 43 | + // See LedgerTxnOfferSQL.cpp::loadOffersByAccountAndAsset |
| 44 | + break; |
| 45 | + case TRUSTLINE: |
| 46 | + // Validate trustline. |
| 47 | + validateTrustLineKey(ledgerVersion, key); |
| 48 | + break; |
| 49 | + case CLAIMABLE_BALANCE: |
| 50 | + break; |
| 51 | + case LIQUIDITY_POOL: |
| 52 | + break; |
| 53 | + case CONTRACT_DATA: |
| 54 | + break; |
| 55 | + case CONTRACT_CODE: |
| 56 | + break; |
| 57 | + case CONFIG_SETTING: |
| 58 | + break; |
| 59 | + case TTL: |
| 60 | + break; |
| 61 | + default: |
| 62 | + throw std::runtime_error("Unknown key type"); |
| 63 | + } |
| 64 | +} |
| 65 | +void |
| 66 | +enforcePostLoadInvariants(LedgerKey const& key, |
| 67 | + std::shared_ptr<LedgerEntry const> const& entry) |
| 68 | +{ |
| 69 | + if (!entry) |
| 70 | + { |
| 71 | + return; |
| 72 | + } |
| 73 | + releaseAssert(key.type() == entry->data.type()); |
| 74 | + switch (key.type()) |
| 75 | + { |
| 76 | + case ACCOUNT: |
| 77 | + // LedgerTxnRoot::loadAccount SQL enforces |
| 78 | + // invariants post-load. |
| 79 | + // It decodes the result of the query and ensures |
| 80 | + // the account signers are sorted in ascending order. |
| 81 | + releaseAssert( |
| 82 | + std::adjacent_find(entry->data.account().signers.begin(), |
| 83 | + entry->data.account().signers.end(), |
| 84 | + [](Signer const& lhs, Signer const& rhs) { |
| 85 | + return !(lhs.key < rhs.key); |
| 86 | + }) == entry->data.account().signers.end()); |
| 87 | + break; |
| 88 | + case DATA: |
| 89 | + // No invariants. |
| 90 | + break; |
| 91 | + case OFFER: |
| 92 | + break; |
| 93 | + case TRUSTLINE: |
| 94 | + break; |
| 95 | + case CLAIMABLE_BALANCE: |
| 96 | + break; |
| 97 | + case LIQUIDITY_POOL: |
| 98 | + break; |
| 99 | + case CONTRACT_DATA: |
| 100 | + break; |
| 101 | + case CONTRACT_CODE: |
| 102 | + break; |
| 103 | + case CONFIG_SETTING: |
| 104 | + break; |
| 105 | + case TTL: |
| 106 | + break; |
| 107 | + default: |
| 108 | + throw std::runtime_error("Unknown key type"); |
| 109 | + } |
| 110 | +}; |
| 111 | +} |
30 | 112 | LedgerEntryPtr
|
31 | 113 | LedgerEntryPtr::Init(std::shared_ptr<InternalLedgerEntry> const& lePtr)
|
32 | 114 | {
|
@@ -2986,9 +3068,17 @@ LedgerTxnRoot::Impl::prefetch(UnorderedSet<LedgerKey> const& keys)
|
2986 | 3068 | {
|
2987 | 3069 | insertIfNotLoaded(keysToSearch, key);
|
2988 | 3070 | }
|
2989 |
| - |
| 3071 | + for (auto key : keys) |
| 3072 | + { |
| 3073 | + enforcePreLoadInvariants(key, mHeader->ledgerVersion); |
| 3074 | + } |
2990 | 3075 | auto blLoad = mApp.getBucketManager().loadKeys(keysToSearch);
|
2991 |
| - cacheResult(populateLoadedEntries(keysToSearch, blLoad)); |
| 3076 | + auto loadedEntries = populateLoadedEntries(keysToSearch, blLoad); |
| 3077 | + for (auto entry : loadedEntries) |
| 3078 | + { |
| 3079 | + enforcePostLoadInvariants(entry.first, entry.second); |
| 3080 | + } |
| 3081 | + cacheResult(loadedEntries); |
2992 | 3082 | }
|
2993 | 3083 | else
|
2994 | 3084 | {
|
@@ -3620,86 +3710,10 @@ LedgerTxnRoot::Impl::getNewestVersion(InternalLedgerKey const& gkey) const
|
3620 | 3710 | }
|
3621 | 3711 |
|
3622 | 3712 | std::shared_ptr<LedgerEntry const> entry;
|
3623 |
| - auto enforcePreLoadInvariants = [&](LedgerKey const& key) { |
3624 |
| - switch (key.type()) |
3625 |
| - { |
3626 |
| - case ACCOUNT: |
3627 |
| - break; |
3628 |
| - case DATA: |
3629 |
| - break; |
3630 |
| - case OFFER: |
3631 |
| - // Ensure offer is not XLM -- possibly? |
3632 |
| - // special case for offer loading from allow trust op frame? |
3633 |
| - // See LedgerTxnOfferSQL.cpp::loadOffersByAccountAndAsset |
3634 |
| - break; |
3635 |
| - case TRUSTLINE: |
3636 |
| - // Validate trustline. |
3637 |
| - validateTrustLineKey(mHeader->ledgerVersion, key); |
3638 |
| - break; |
3639 |
| - case CLAIMABLE_BALANCE: |
3640 |
| - break; |
3641 |
| - case LIQUIDITY_POOL: |
3642 |
| - break; |
3643 |
| - case CONTRACT_DATA: |
3644 |
| - break; |
3645 |
| - case CONTRACT_CODE: |
3646 |
| - break; |
3647 |
| - case CONFIG_SETTING: |
3648 |
| - break; |
3649 |
| - case TTL: |
3650 |
| - break; |
3651 |
| - default: |
3652 |
| - throw std::runtime_error("Unknown key type"); |
3653 |
| - } |
3654 |
| - }; |
3655 |
| - auto enforcePostLoadInvariants = |
3656 |
| - [&](LedgerKey const& key, |
3657 |
| - std::shared_ptr<LedgerEntry const> const& entry) { |
3658 |
| - if (!entry) |
3659 |
| - { |
3660 |
| - return; |
3661 |
| - } |
3662 |
| - releaseAssert(key.type() == entry->data.type()); |
3663 |
| - switch (key.type()) |
3664 |
| - { |
3665 |
| - case ACCOUNT: |
3666 |
| - // LedgerTxnRoot::loadAccount SQL enforces |
3667 |
| - // invariants post-load. |
3668 |
| - // It decodes the result of the query and ensures |
3669 |
| - // the account signers are sorted in ascending order. |
3670 |
| - releaseAssert(std::adjacent_find( |
3671 |
| - entry->data.account().signers.begin(), |
3672 |
| - entry->data.account().signers.end(), |
3673 |
| - [](Signer const& lhs, Signer const& rhs) { |
3674 |
| - return !(lhs.key < rhs.key); |
3675 |
| - }) == entry->data.account().signers.end()); |
3676 |
| - break; |
3677 |
| - case DATA: |
3678 |
| - // No invariants. |
3679 |
| - break; |
3680 |
| - case OFFER: |
3681 |
| - break; |
3682 |
| - case TRUSTLINE: |
3683 |
| - break; |
3684 |
| - case CLAIMABLE_BALANCE: |
3685 |
| - break; |
3686 |
| - case LIQUIDITY_POOL: |
3687 |
| - break; |
3688 |
| - case CONTRACT_DATA: |
3689 |
| - break; |
3690 |
| - case CONTRACT_CODE: |
3691 |
| - break; |
3692 |
| - case CONFIG_SETTING: |
3693 |
| - break; |
3694 |
| - case TTL: |
3695 |
| - break; |
3696 |
| - default: |
3697 |
| - throw std::runtime_error("Unknown key type"); |
3698 |
| - } |
3699 |
| - }; |
| 3713 | + |
3700 | 3714 | try
|
3701 | 3715 | {
|
3702 |
| - enforcePreLoadInvariants(key); |
| 3716 | + enforcePreLoadInvariants(key, mHeader->ledgerVersion); |
3703 | 3717 | if (mApp.getConfig().isUsingBucketListDB() && key.type() != OFFER)
|
3704 | 3718 | {
|
3705 | 3719 | entry = mApp.getBucketManager().getLedgerEntry(key);
|
|
0 commit comments