Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LedgerChangeReader: Support State Expiration & Eviction #4941

Merged
merged 13 commits into from
Jul 3, 2023
40 changes: 40 additions & 0 deletions ingest/change.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ingest

import (
"bytes"
"fmt"

"github.com/stellar/go/support/errors"
"github.com/stellar/go/xdr"
Expand Down Expand Up @@ -68,6 +69,45 @@ func GetChangesFromLedgerEntryChanges(ledgerEntryChanges xdr.LedgerEntryChanges)
return changes
}

// GetChangesFromLedgerEntryEvictions transforms evicted LedgerKeys to []Change.
// The generated changes always remove the entries.
func GetChangesFromLedgerEntryEvictions(keys []xdr.LedgerKey) ([]Change, error) {
changes := []Change{}

for _, key := range keys {
state := xdr.LedgerEntry{}
switch key.Type {
case xdr.LedgerEntryTypeContractData:
err := state.Data.SetContractData(&xdr.ContractDataEntry{
Contract: key.ContractData.Contract,
Key: key.ContractData.Key,
Durability: key.ContractData.Durability,
})
if err != nil {
return nil, errors.Wrap(err, "error setting ContractDataEntry")
}
case xdr.LedgerEntryTypeContractCode:
err := state.Data.SetContractCode(&xdr.ContractCodeEntry{
Hash: key.ContractCode.Hash,
})
if err != nil {
return nil, errors.Wrap(err, "error setting ContractCodeEntry")
}
default:
// Currently only contractData and contractCode are evicted by core, so
// we only need to handle those two.
return nil, fmt.Errorf("invalid LedgerEntry eviction type: %s", key.Type)
}
changes = append(changes, Change{
Type: key.Type,
Pre: &state,
Post: nil,
})
}

return changes, nil
}

// LedgerEntryChangeType returns type in terms of LedgerEntryChangeType.
func (c *Change) LedgerEntryChangeType() xdr.LedgerEntryChangeType {
switch {
Expand Down
15 changes: 13 additions & 2 deletions ingest/ledger_change_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ type ledgerChangeReaderState int
const (
// feeChangesState is active when LedgerChangeReader is reading fee changes.
feeChangesState ledgerChangeReaderState = iota
// feeChangesState is active when LedgerChangeReader is reading transaction meta changes.
// metaChangesState is active when LedgerChangeReader is reading transaction meta changes.
metaChangesState
// feeChangesState is active when LedgerChangeReader is reading upgrade changes.
// evictionChangesState is active when LedgerChangeReader is reading ledger entry evictions.
evictionChangesState
// upgradeChanges is active when LedgerChangeReader is reading upgrade changes.
upgradeChangesState
)

Expand Down Expand Up @@ -122,6 +124,15 @@ func (r *LedgerChangeReader) Read() (Change, error) {
r.pending = append(r.pending, metaChanges...)
}
return r.Read()
case evictionChangesState:
// Get contract ledgerEntry evictions
changes, err := GetChangesFromLedgerEntryEvictions(r.ledgerCloseMeta.EvictedLedgerKeys())
if err != nil {
return Change{}, err
}
r.pending = append(r.pending, changes...)
r.state++
paulbellamy marked this conversation as resolved.
Show resolved Hide resolved
return r.Read()
case upgradeChangesState:
// Get upgrade changes
if r.upgradeIndex < len(r.LedgerTransactionReader.ledgerCloseMeta.UpgradesProcessing()) {
Expand Down
Loading