diff --git a/cmd/soroban-rpc/internal/db/ledger_test.go b/cmd/soroban-rpc/internal/db/ledger_test.go index 362f33653..bbbfdbee8 100644 --- a/cmd/soroban-rpc/internal/db/ledger_test.go +++ b/cmd/soroban-rpc/internal/db/ledger_test.go @@ -11,8 +11,8 @@ import ( func createLedger(ledgerSequence uint32) xdr.LedgerCloseMeta { return xdr.LedgerCloseMeta{ - V: 2, - V2: &xdr.LedgerCloseMetaV2{ + V: 1, + V1: &xdr.LedgerCloseMetaV1{ LedgerHeader: xdr.LedgerHeaderHistoryEntry{ Hash: xdr.Hash{}, Header: xdr.LedgerHeader{ diff --git a/cmd/soroban-rpc/internal/db/ledgerentry.go b/cmd/soroban-rpc/internal/db/ledgerentry.go index 87fbd75dd..e42f74c20 100644 --- a/cmd/soroban-rpc/internal/db/ledgerentry.go +++ b/cmd/soroban-rpc/internal/db/ledgerentry.go @@ -24,9 +24,9 @@ type LedgerEntryReader interface { } type LedgerKeyAndEntry struct { - Key xdr.LedgerKey - Entry xdr.LedgerEntry - ExpirationLedgerSeq *uint32 // optional expiration ledger seq, when applicable. + Key xdr.LedgerKey + Entry xdr.LedgerEntry + LiveUntilLedgerSeq *uint32 // optional live-until ledger seq, when applicable. } type LedgerEntryReadTx interface { @@ -228,7 +228,7 @@ func GetLedgerEntry(tx LedgerEntryReadTx, key xdr.LedgerKey) (bool, xdr.LedgerEn return false, xdr.LedgerEntry{}, nil, nil case 1: // expected length - return true, keyEntries[0].Entry, keyEntries[0].ExpirationLedgerSeq, nil + return true, keyEntries[0].Entry, keyEntries[0].LiveUntilLedgerSeq, nil default: return false, xdr.LedgerEntry{}, nil, fmt.Errorf("multiple entries (%d) for key %v", len(keyEntries), key) } @@ -314,8 +314,8 @@ func (l *ledgerEntryReadTx) GetLedgerEntries(keys ...xdr.LedgerKey) ([]LedgerKey if err := xdr.SafeUnmarshal([]byte(encodedExpEntry), &expEntry); err != nil { return nil, errors.Wrap(err, "cannot decode expiration ledger entry from DB") } - expSeq := uint32(expEntry.Data.Expiration.ExpirationLedgerSeq) - result = append(result, LedgerKeyAndEntry{key, entry, &expSeq}) + liveUntilSeq := uint32(expEntry.Data.Ttl.LiveUntilLedgerSeq) + result = append(result, LedgerKeyAndEntry{key, entry, &liveUntilSeq}) } return result, nil diff --git a/cmd/soroban-rpc/internal/db/ledgerentry_test.go b/cmd/soroban-rpc/internal/db/ledgerentry_test.go index 5da7791ef..3027bc72a 100644 --- a/cmd/soroban-rpc/internal/db/ledgerentry_test.go +++ b/cmd/soroban-rpc/internal/db/ledgerentry_test.go @@ -83,11 +83,11 @@ func TestGoldenPath(t *testing.T) { ledgerSequence := uint32(23) assert.NoError(t, tx.Commit(ledgerSequence)) - present, obtainedEntry, obtainedLedgerSequence, expSeq := getLedgerEntryAndLatestLedgerSequence(t, db, key) + present, obtainedEntry, obtainedLedgerSequence, liveUntilSeq := getLedgerEntryAndLatestLedgerSequence(t, db, key) assert.True(t, present) assert.Equal(t, ledgerSequence, obtainedLedgerSequence) - require.NotNil(t, expSeq) - assert.Equal(t, uint32(expLegerEntry.Data.Expiration.ExpirationLedgerSeq), *expSeq) + require.NotNil(t, liveUntilSeq) + assert.Equal(t, uint32(expLegerEntry.Data.Ttl.LiveUntilLedgerSeq), *liveUntilSeq) assert.Equal(t, obtainedEntry.Data.Type, xdr.LedgerEntryTypeContractData) assert.Equal(t, xdr.Hash{0xca, 0xfe}, *obtainedEntry.Data.ContractData.Contract.ContractId) assert.Equal(t, six, *obtainedEntry.Data.ContractData.Val.U32) @@ -108,9 +108,9 @@ func TestGoldenPath(t *testing.T) { ledgerSequence = uint32(24) assert.NoError(t, tx.Commit(ledgerSequence)) - present, obtainedEntry, obtainedLedgerSequence, expSeq = getLedgerEntryAndLatestLedgerSequence(t, db, key) + present, obtainedEntry, obtainedLedgerSequence, liveUntilSeq = getLedgerEntryAndLatestLedgerSequence(t, db, key) assert.True(t, present) - require.NotNil(t, expSeq) + require.NotNil(t, liveUntilSeq) assert.Equal(t, ledgerSequence, obtainedLedgerSequence) assert.Equal(t, eight, *obtainedEntry.Data.ContractData.Val.U32) @@ -124,9 +124,9 @@ func TestGoldenPath(t *testing.T) { ledgerSequence = uint32(25) assert.NoError(t, tx.Commit(ledgerSequence)) - present, _, obtainedLedgerSequence, expSeq = getLedgerEntryAndLatestLedgerSequence(t, db, key) + present, _, obtainedLedgerSequence, liveUntilSeq = getLedgerEntryAndLatestLedgerSequence(t, db, key) assert.False(t, present) - assert.Nil(t, expSeq) + assert.Nil(t, liveUntilSeq) assert.Equal(t, ledgerSequence, obtainedLedgerSequence) obtainedLedgerSequence, err = NewLedgerEntryReader(db).GetLatestLedgerSequence(context.Background()) @@ -194,9 +194,9 @@ func getContractDataLedgerEntry(t require.TestingT, data xdr.ContractDataEntry) func getExpirationLedgerEntry(key xdr.LedgerKey) xdr.LedgerEntry { var expLegerEntry xdr.LedgerEntry - expLegerEntry.Data.Expiration = &xdr.ExpirationEntry{ - KeyHash: key.Expiration.KeyHash, - ExpirationLedgerSeq: 100, + expLegerEntry.Data.Ttl = &xdr.TtlEntry{ + KeyHash: key.Ttl.KeyHash, + LiveUntilLedgerSeq: 100, } expLegerEntry.Data.Type = key.Type return expLegerEntry diff --git a/cmd/soroban-rpc/internal/ingest/service_test.go b/cmd/soroban-rpc/internal/ingest/service_test.go index 9c76a81fd..4993d326f 100644 --- a/cmd/soroban-rpc/internal/ingest/service_test.go +++ b/cmd/soroban-rpc/internal/ingest/service_test.go @@ -176,8 +176,8 @@ func TestIngestion(t *testing.T) { }, } ledger := xdr.LedgerCloseMeta{ - V: 2, - V2: &xdr.LedgerCloseMetaV2{ + V: 1, + V1: &xdr.LedgerCloseMetaV1{ LedgerHeader: xdr.LedgerHeaderHistoryEntry{Header: xdr.LedgerHeader{LedgerVersion: 10}}, TxSet: xdr.GeneralizedTransactionSet{ V: 1, diff --git a/cmd/soroban-rpc/internal/methods/get_events_test.go b/cmd/soroban-rpc/internal/methods/get_events_test.go index 86c2086d4..5a1ba6388 100644 --- a/cmd/soroban-rpc/internal/methods/get_events_test.go +++ b/cmd/soroban-rpc/internal/methods/get_events_test.go @@ -1121,8 +1121,8 @@ func ledgerCloseMetaWithEvents(sequence uint32, closeTimestamp int64, txMeta ... } return xdr.LedgerCloseMeta{ - V: 2, - V2: &xdr.LedgerCloseMetaV2{ + V: 1, + V1: &xdr.LedgerCloseMetaV1{ LedgerHeader: xdr.LedgerHeaderHistoryEntry{ Hash: xdr.Hash{}, Header: xdr.LedgerHeader{ diff --git a/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go b/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go index 124ec6a33..474b3b8da 100644 --- a/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go +++ b/cmd/soroban-rpc/internal/methods/get_latest_ledger_test.go @@ -60,8 +60,8 @@ func (ledgerReader *ConstantLedgerReader) StreamAllLedgers(ctx context.Context, func createLedger(ledgerSequence uint32, protocolVersion uint32, hash byte) xdr.LedgerCloseMeta { return xdr.LedgerCloseMeta{ - V: 2, - V2: &xdr.LedgerCloseMetaV2{ + V: 1, + V1: &xdr.LedgerCloseMetaV1{ LedgerHeader: xdr.LedgerHeaderHistoryEntry{ Hash: xdr.Hash{hash}, Header: xdr.LedgerHeader{ diff --git a/cmd/soroban-rpc/internal/methods/get_ledger_entries.go b/cmd/soroban-rpc/internal/methods/get_ledger_entries.go index 00c3ad22a..2e0076ad4 100644 --- a/cmd/soroban-rpc/internal/methods/get_ledger_entries.go +++ b/cmd/soroban-rpc/internal/methods/get_ledger_entries.go @@ -68,9 +68,9 @@ func NewGetLedgerEntriesHandler(logger *log.Entry, ledgerEntryReader db.LedgerEn Message: fmt.Sprintf("cannot unmarshal key value %s at index %d", requestKey, i), } } - if ledgerKey.Type == xdr.LedgerEntryTypeExpiration { + if ledgerKey.Type == xdr.LedgerEntryTypeTtl { logger.WithField("request", request). - Infof("could not provide ledger expiration entry %s at index %d from getLedgerEntries request", requestKey, i) + Infof("could not provide ledger ttl entry %s at index %d from getLedgerEntries request", requestKey, i) return GetLedgerEntriesResponse{}, &jrpc2.Error{ Code: jrpc2.InvalidParams, Message: ErrLedgerExpirationEntriesCannotBeQueriedDirectly, @@ -124,7 +124,7 @@ func NewGetLedgerEntriesHandler(logger *log.Entry, ledgerEntryReader db.LedgerEn Key: request.Keys[i], XDR: ledgerXDR, LastModifiedLedger: int64(ledgerKeyAndEntry.Entry.LastModifiedLedgerSeq), - ExpirationLedger: ledgerKeyAndEntry.ExpirationLedgerSeq, + ExpirationLedger: ledgerKeyAndEntry.LiveUntilLedgerSeq, }) } diff --git a/cmd/soroban-rpc/internal/methods/get_ledger_entry.go b/cmd/soroban-rpc/internal/methods/get_ledger_entry.go index 1da93f9dd..d3eac6dc9 100644 --- a/cmd/soroban-rpc/internal/methods/get_ledger_entry.go +++ b/cmd/soroban-rpc/internal/methods/get_ledger_entry.go @@ -52,7 +52,7 @@ func NewGetLedgerEntryHandler(logger *log.Entry, ledgerEntryReader db.LedgerEntr return GetLedgerEntryResponse{}, invalidLedgerKeyXdrError } - if key.Type == xdr.LedgerEntryTypeExpiration { + if key.Type == xdr.LedgerEntryTypeTtl { return GetLedgerEntryResponse{}, &jrpc2.Error{ Code: jrpc2.InvalidParams, Message: ErrLedgerExpirationEntriesCannotBeQueriedDirectly, diff --git a/cmd/soroban-rpc/internal/methods/get_transaction_test.go b/cmd/soroban-rpc/internal/methods/get_transaction_test.go index e0c3e5721..1b30cb762 100644 --- a/cmd/soroban-rpc/internal/methods/get_transaction_test.go +++ b/cmd/soroban-rpc/internal/methods/get_transaction_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stellar/go/network" + "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/transactions" ) @@ -70,8 +71,8 @@ func txMeta(acctSeq uint32, successful bool) xdr.LedgerCloseMeta { }, } return xdr.LedgerCloseMeta{ - V: 2, - V2: &xdr.LedgerCloseMetaV2{ + V: 1, + V1: &xdr.LedgerCloseMetaV1{ LedgerHeader: xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ ScpValue: xdr.StellarValue{ @@ -134,11 +135,11 @@ func TestGetTransaction(t *testing.T) { tx, err = GetTransaction(store, GetTransactionRequest{hash}) assert.NoError(t, err) - expectedTxResult, err := xdr.MarshalBase64(meta.V2.TxProcessing[0].Result.Result) + expectedTxResult, err := xdr.MarshalBase64(meta.V1.TxProcessing[0].Result.Result) assert.NoError(t, err) expectedEnvelope, err := xdr.MarshalBase64(txEnvelope(1)) assert.NoError(t, err) - expectedTxMeta, err := xdr.MarshalBase64(meta.V2.TxProcessing[0].TxApplyProcessing) + expectedTxMeta, err := xdr.MarshalBase64(meta.V1.TxProcessing[0].TxApplyProcessing) assert.NoError(t, err) assert.Equal(t, GetTransactionResponse{ Status: TransactionStatusSuccess, @@ -182,11 +183,11 @@ func TestGetTransaction(t *testing.T) { xdrHash = txHash(2) hash = hex.EncodeToString(xdrHash[:]) - expectedTxResult, err = xdr.MarshalBase64(meta.V2.TxProcessing[0].Result.Result) + expectedTxResult, err = xdr.MarshalBase64(meta.V1.TxProcessing[0].Result.Result) assert.NoError(t, err) expectedEnvelope, err = xdr.MarshalBase64(txEnvelope(2)) assert.NoError(t, err) - expectedTxMeta, err = xdr.MarshalBase64(meta.V2.TxProcessing[0].TxApplyProcessing) + expectedTxMeta, err = xdr.MarshalBase64(meta.V1.TxProcessing[0].TxApplyProcessing) assert.NoError(t, err) tx, err = GetTransaction(store, GetTransactionRequest{hash}) diff --git a/cmd/soroban-rpc/internal/methods/simulate_transaction.go b/cmd/soroban-rpc/internal/methods/simulate_transaction.go index 638a6a7b5..cd6a8bae1 100644 --- a/cmd/soroban-rpc/internal/methods/simulate_transaction.go +++ b/cmd/soroban-rpc/internal/methods/simulate_transaction.go @@ -86,10 +86,10 @@ func NewSimulateTransactionHandler(logger *log.Entry, ledgerEntryReader db.Ledge footprint := xdr.LedgerFootprint{} switch op.Body.Type { case xdr.OperationTypeInvokeHostFunction: - case xdr.OperationTypeBumpFootprintExpiration, xdr.OperationTypeRestoreFootprint: + case xdr.OperationTypeExtendFootprintTtl, xdr.OperationTypeRestoreFootprint: if txEnvelope.Type != xdr.EnvelopeTypeEnvelopeTypeTx && txEnvelope.V1.Tx.Ext.V != 1 { return SimulateTransactionResponse{ - Error: "To perform a SimulateTransaction for BumpFootprintExpiration or RestoreFootprint operations, SorobanTransactionData must be provided", + Error: "To perform a SimulateTransaction for ExtendFootprintTtl or RestoreFootprint operations, SorobanTransactionData must be provided", } } footprint = txEnvelope.V1.Tx.Ext.SorobanData.Resources.Footprint @@ -177,8 +177,8 @@ func getBucketListSize(ctx context.Context, ledgerReader db.LedgerReader, latest if !ok { return 0, fmt.Errorf("missing meta for latest ledger (%d)", latestLedger) } - if closeMeta.V != 2 { + if closeMeta.V != 1 { return 0, fmt.Errorf("latest ledger (%d) meta has unexpected verion (%d)", latestLedger, closeMeta.V) } - return uint64(closeMeta.V2.TotalByteSizeOfBucketList), nil + return uint64(closeMeta.V1.TotalByteSizeOfBucketList), nil } diff --git a/cmd/soroban-rpc/internal/preflight/preflight.go b/cmd/soroban-rpc/internal/preflight/preflight.go index dc36810c8..a883b94c2 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight.go +++ b/cmd/soroban-rpc/internal/preflight/preflight.go @@ -46,7 +46,7 @@ func SnapshotSourceGet(handle C.uintptr_t, cLedgerKey C.xdr_t) C.xdr_t { if err := xdr.SafeUnmarshal(ledgerKeyXDR, &ledgerKey); err != nil { panic(err) } - // TODO : the expiration sequence here is being ignored for now; it should be passed downstream. + // TODO : the live-until sequence here is being ignored for now; it should be passed downstream. present, entry, _, err := db.GetLedgerEntry(h.readTx, ledgerKey) if err != nil { h.logger.WithError(err).Error("SnapshotSourceGet(): GetLedgerEntry() failed") @@ -118,7 +118,7 @@ func GetPreflight(ctx context.Context, params PreflightParameters) (Preflight, e switch params.OpBody.Type { case xdr.OperationTypeInvokeHostFunction: return getInvokeHostFunctionPreflight(params) - case xdr.OperationTypeBumpFootprintExpiration, xdr.OperationTypeRestoreFootprint: + case xdr.OperationTypeExtendFootprintTtl, xdr.OperationTypeRestoreFootprint: return getFootprintExpirationPreflight(params) default: return Preflight{}, fmt.Errorf("unsupported operation type: %s", params.OpBody.Type.String()) @@ -144,7 +144,7 @@ func getFootprintExpirationPreflight(params PreflightParameters) (Preflight, err return Preflight{}, err } - res := C.preflight_footprint_expiration_op( + res := C.preflight_footprint_ttl_op( C.uintptr_t(handle), C.uint64_t(params.BucketListSize), opBodyCXDR, @@ -182,16 +182,16 @@ func getInvokeHostFunctionPreflight(params PreflightParameters) (Preflight, erro } sourceAccountCXDR := CXDR(sourceAccountXDR) - hasConfig, stateExpirationConfig, expSeq, err := db.GetLedgerEntry(params.LedgerEntryReadTx, xdr.LedgerKey{ + hasConfig, stateExpirationConfig, liveUntilSeq, err := db.GetLedgerEntry(params.LedgerEntryReadTx, xdr.LedgerKey{ Type: xdr.LedgerEntryTypeConfigSetting, ConfigSetting: &xdr.LedgerKeyConfigSetting{ - ConfigSettingId: xdr.ConfigSettingIdConfigSettingStateExpiration, + ConfigSettingId: xdr.ConfigSettingIdConfigSettingStateArchival, }, }) if err != nil { return Preflight{}, err } - if expSeq != nil { + if liveUntilSeq != nil { return Preflight{}, errors.New("configuration setting are not expected to be expiring, yet, an expiration ledger sequence was found for ledger entry") } if !hasConfig { @@ -203,17 +203,17 @@ func getInvokeHostFunctionPreflight(params PreflightParameters) (Preflight, erro return Preflight{}, err } - stateExpiration := stateExpirationConfig.Data.MustConfigSetting().MustStateExpirationSettings() + stateArchival := stateExpirationConfig.Data.MustConfigSetting().MustStateArchivalSettings() li := C.ledger_info_t{ network_passphrase: C.CString(params.NetworkPassphrase), sequence_number: C.uint32_t(simulationLedgerSeq), protocol_version: 20, timestamp: C.uint64_t(time.Now().Unix()), // Current base reserve is 0.5XLM (in stroops) - base_reserve: 5_000_000, - min_temp_entry_expiration: C.uint(stateExpiration.MinTempEntryExpiration), - min_persistent_entry_expiration: C.uint(stateExpiration.MinPersistentEntryExpiration), - max_entry_expiration: C.uint(stateExpiration.MaxEntryExpiration), + base_reserve: 5_000_000, + min_temp_entry_ttl: C.uint(stateArchival.MinTemporaryTtl), + min_persistent_entry_ttl: C.uint(stateArchival.MinPersistentTtl), + max_entry_ttl: C.uint(stateArchival.MaxEntryTtl), } handle := cgo.NewHandle(snapshotSourceHandle{params.LedgerEntryReadTx, params.Logger}) diff --git a/cmd/soroban-rpc/internal/preflight/preflight_test.go b/cmd/soroban-rpc/internal/preflight/preflight_test.go index b3215f49d..8b9a223c4 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight_test.go +++ b/cmd/soroban-rpc/internal/preflight/preflight_test.go @@ -154,14 +154,14 @@ var mockLedgerEntriesWithoutExpirations = []xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ Type: xdr.LedgerEntryTypeConfigSetting, ConfigSetting: &xdr.ConfigSettingEntry{ - ConfigSettingId: xdr.ConfigSettingIdConfigSettingStateExpiration, - StateExpirationSettings: &xdr.StateExpirationSettings{ - MaxEntryExpiration: 100, - MinTempEntryExpiration: 100, - MinPersistentEntryExpiration: 100, + ConfigSettingId: xdr.ConfigSettingIdConfigSettingStateArchival, + StateArchivalSettings: &xdr.StateArchivalSettings{ + MaxEntryTtl: 100, + MinTemporaryTtl: 100, + MinPersistentTtl: 100, PersistentRentRateDenominator: 100, TempRentRateDenominator: 100, - MaxEntriesToExpire: 100, + MaxEntriesToArchive: 100, BucketListSizeWindowSampleSize: 100, EvictionScanSize: 100, }, @@ -210,11 +210,11 @@ var mockLedgerEntries = func() []xdr.LedgerEntry { expirationEntry := xdr.LedgerEntry{ LastModifiedLedgerSeq: entry.LastModifiedLedgerSeq, Data: xdr.LedgerEntryData{ - Type: xdr.LedgerEntryTypeExpiration, - Expiration: &xdr.ExpirationEntry{ + Type: xdr.LedgerEntryTypeTtl, + Ttl: &xdr.TtlEntry{ KeyHash: sha256.Sum256(bin), - // Make sure it doesn't expire - ExpirationLedgerSeq: 1000, + // Make sure it doesn't ttl + LiveUntilLedgerSeq: 1000, }, }, } diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index 1634df6c3..f196d778c 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -17,10 +17,11 @@ import ( "github.com/stellar/go/strkey" "github.com/stellar/go/txnbuild" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gotest.tools/v3/icmd" + + "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/methods" ) func cargoTest(t *testing.T, name string) { @@ -218,7 +219,7 @@ func TestCLIRestore(t *testing.T) { assert.Equal(t, fmt.Sprintf("New expiration ledger: %d", newExpirationSeq), restoreOutput) // test to see that we get an error when requesting the expiration ledger entry explicitly. - ledgerExpirationEntry := getExpirationKey(t, getCounterLedgerKey(parseContractStrKey(t, strkeyContractID))) + ledgerExpirationEntry := getTtlKey(t, getCounterLedgerKey(parseContractStrKey(t, strkeyContractID))) ledgerExpirationEntryB64, err := xdr.MarshalBase64(ledgerExpirationEntry) require.NoError(t, err) var getLedgerEntryResult methods.GetLedgerEntryResponse @@ -237,13 +238,13 @@ func TestCLIRestore(t *testing.T) { require.Contains(t, err.Error(), methods.ErrLedgerExpirationEntriesCannotBeQueriedDirectly) } -func getExpirationKey(t *testing.T, key xdr.LedgerKey) xdr.LedgerKey { +func getTtlKey(t *testing.T, key xdr.LedgerKey) xdr.LedgerKey { assert.True(t, key.Type == xdr.LedgerEntryTypeContractCode || key.Type == xdr.LedgerEntryTypeContractData) binKey, err := key.MarshalBinary() assert.NoError(t, err) return xdr.LedgerKey{ - Type: xdr.LedgerEntryTypeExpiration, - Expiration: &xdr.LedgerKeyExpiration{ + Type: xdr.LedgerEntryTypeTtl, + Ttl: &xdr.LedgerKeyTtl{ KeyHash: sha256.Sum256(binKey), }, } diff --git a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go index e1c02b8e4..2e4ba5428 100644 --- a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go +++ b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go @@ -159,7 +159,7 @@ func preflightTransactionParamsLocally(t *testing.T, params txnbuild.Transaction auth = append(auth, a) } v.Auth = auth - case *txnbuild.BumpFootprintExpiration: + case *txnbuild.ExtendFootprintTtl: require.Len(t, response.Results, 0) v.Ext = xdr.TransactionExt{ V: 1, @@ -236,7 +236,7 @@ func TestSimulateTransactionSucceeds(t *testing.T) { ReadBytes: 48, WriteBytes: 7048, }, - RefundableFee: 20056, + ResourceFee: 20056, } // First, decode and compare the transaction data so we get a decent diff if it fails. @@ -247,7 +247,7 @@ func TestSimulateTransactionSucceeds(t *testing.T) { assert.InDelta(t, uint32(expectedTransactionData.Resources.Instructions), uint32(transactionData.Resources.Instructions), 100000) assert.InDelta(t, uint32(expectedTransactionData.Resources.ReadBytes), uint32(transactionData.Resources.ReadBytes), 10) assert.InDelta(t, uint32(expectedTransactionData.Resources.WriteBytes), uint32(transactionData.Resources.WriteBytes), 100) - assert.InDelta(t, int64(expectedTransactionData.RefundableFee), int64(transactionData.RefundableFee), 1000) + assert.InDelta(t, int64(expectedTransactionData.ResourceFee), int64(transactionData.ResourceFee), 1000) // Then decode and check the result xdr, separately so we get a decent diff if it fails. assert.Len(t, result.Results, 1) @@ -494,7 +494,7 @@ func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { assert.Equal(t, xdr.Hash(contractHash), ro2.ContractCode.Hash) assert.NoError(t, err) - assert.NotZero(t, obtainedTransactionData.RefundableFee) + assert.NotZero(t, obtainedTransactionData.ResourceFee) assert.NotZero(t, obtainedTransactionData.Resources.Instructions) assert.NotZero(t, obtainedTransactionData.Resources.ReadBytes) assert.NotZero(t, obtainedTransactionData.Resources.WriteBytes) @@ -756,8 +756,8 @@ func TestSimulateTransactionBumpAndRestoreFootprint(t *testing.T) { SourceAccount: &account, IncrementSequenceNum: true, Operations: []txnbuild.Operation{ - &txnbuild.BumpFootprintExpiration{ - LedgersToExpire: 20, + &txnbuild.ExtendFootprintTtl{ + ExtendTo: 20, Ext: xdr.TransactionExt{ V: 1, SorobanData: &xdr.SorobanTransactionData{ @@ -923,7 +923,7 @@ func waitForLedgerEntryToExpire(t *testing.T, client *jrpc2.Client, ledgerKey xd require.NoError(t, err) require.NotEmpty(t, result.Entries) require.NoError(t, xdr.SafeUnmarshalBase64(result.Entries[0].XDR, &entry)) - require.NotEqual(t, xdr.LedgerEntryTypeExpiration, entry.Type) + require.NotEqual(t, xdr.LedgerEntryTypeTtl, entry.Type) expirationLedgerSeq := xdr.Uint32(*result.Entries[0].ExpirationLedger) // See https://soroban.stellar.org/docs/fundamentals-and-concepts/state-expiration#expiration-ledger currentLedger := result.LatestLedger + 1 @@ -1159,7 +1159,7 @@ func TestSimulateSystemEvent(t *testing.T) { require.NoError(t, err) assert.InDelta(t, 7260, uint32(transactionData.Resources.ReadBytes), 200) - assert.InDelta(t, 45, int64(transactionData.RefundableFee), 10) + assert.InDelta(t, 45, int64(transactionData.ResourceFee), 10) assert.InDelta(t, 104, uint32(transactionData.Resources.WriteBytes), 15) require.GreaterOrEqual(t, len(response.Events), 3) } diff --git a/cmd/soroban-rpc/internal/transactions/transactions_test.go b/cmd/soroban-rpc/internal/transactions/transactions_test.go index cf78976c9..64fabff1f 100644 --- a/cmd/soroban-rpc/internal/transactions/transactions_test.go +++ b/cmd/soroban-rpc/internal/transactions/transactions_test.go @@ -5,8 +5,9 @@ import ( "github.com/stellar/go/network" "github.com/stellar/go/xdr" - "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" "github.com/stretchr/testify/require" + + "github.com/stellar/soroban-tools/cmd/soroban-rpc/internal/daemon/interfaces" ) func expectedTransaction(ledger uint32, feeBump bool) Transaction { @@ -107,8 +108,8 @@ func txMeta(ledgerSequence uint32, feeBump bool) xdr.LedgerCloseMeta { }, } return xdr.LedgerCloseMeta{ - V: 2, - V2: &xdr.LedgerCloseMetaV2{ + V: 1, + V1: &xdr.LedgerCloseMetaV1{ LedgerHeader: xdr.LedgerHeaderHistoryEntry{ Header: xdr.LedgerHeader{ ScpValue: xdr.StellarValue{ diff --git a/cmd/soroban-rpc/lib/preflight.h b/cmd/soroban-rpc/lib/preflight.h index fc01d9f45..627cc54c8 100644 --- a/cmd/soroban-rpc/lib/preflight.h +++ b/cmd/soroban-rpc/lib/preflight.h @@ -9,9 +9,9 @@ typedef struct ledger_info_t { uint64_t timestamp; const char *network_passphrase; uint32_t base_reserve; - uint32_t min_temp_entry_expiration; - uint32_t min_persistent_entry_expiration; - uint32_t max_entry_expiration; + uint32_t min_temp_entry_ttl; + uint32_t min_persistent_entry_ttl; + uint32_t max_entry_ttl; } ledger_info_t; typedef struct xdr_t { @@ -43,11 +43,11 @@ preflight_result_t *preflight_invoke_hf_op(uintptr_t handle, // Go Handle to for const xdr_t source_account, // AccountId XDR const ledger_info_t ledger_info); -preflight_result_t *preflight_footprint_expiration_op(uintptr_t handle, // Go Handle to forward to SnapshotSourceGet - uint64_t bucket_list_size, // Bucket list size of current ledger - const xdr_t op_body, // OperationBody XDR - const xdr_t footprint, // LedgerFootprint XDR - uint32_t current_ledger_seq); // Current ledger sequence +preflight_result_t *preflight_footprint_ttl_op(uintptr_t handle, // Go Handle to forward to SnapshotSourceGet + uint64_t bucket_list_size, // Bucket list size of current ledger + const xdr_t op_body, // OperationBody XDR + const xdr_t footprint, // LedgerFootprint XDR + uint32_t current_ledger_seq); // Current ledger sequence // LedgerKey XDR to LedgerEntry XDR diff --git a/cmd/soroban-rpc/lib/preflight/src/fees.rs b/cmd/soroban-rpc/lib/preflight/src/fees.rs index 86d3a9b44..a48d1a349 100644 --- a/cmd/soroban-rpc/lib/preflight/src/fees.rs +++ b/cmd/soroban-rpc/lib/preflight/src/fees.rs @@ -2,7 +2,7 @@ use anyhow::{bail, ensure, Context, Error, Result}; use ledger_storage::LedgerStorage; use soroban_env_host::budget::Budget; use soroban_env_host::e2e_invoke::{ - extract_rent_changes, get_ledger_changes, ExpirationEntryMap, LedgerEntryChange, + extract_rent_changes, get_ledger_changes, LedgerEntryChange, TtlEntryMap, }; use soroban_env_host::fees::{ compute_rent_fee, compute_transaction_resource_fee, compute_write_fee_per_1kb, @@ -13,13 +13,13 @@ use soroban_env_host::storage::{AccessType, Footprint, Storage}; use soroban_env_host::xdr; use soroban_env_host::xdr::ContractDataDurability::Persistent; use soroban_env_host::xdr::{ - BumpFootprintExpirationOp, ConfigSettingEntry, ConfigSettingId, ContractEventType, - DecoratedSignature, DiagnosticEvent, ExtensionPoint, InvokeHostFunctionOp, LedgerFootprint, - LedgerKey, Memo, MuxedAccount, MuxedAccountMed25519, Operation, OperationBody, Preconditions, + ConfigSettingEntry, ConfigSettingId, ContractEventType, DecoratedSignature, DiagnosticEvent, + ExtendFootprintTtlOp, ExtensionPoint, InvokeHostFunctionOp, LedgerFootprint, LedgerKey, Memo, + MuxedAccount, MuxedAccountMed25519, Operation, OperationBody, Preconditions, RestoreFootprintOp, ScVal, SequenceNumber, Signature, SignatureHint, SorobanResources, SorobanTransactionData, Transaction, TransactionExt, TransactionV1Envelope, Uint256, WriteXdr, }; -use state_expiration::{get_restored_ledger_sequence, ExpirableLedgerEntry}; +use state_ttl::{get_restored_ledger_sequence, TTLLedgerEntry}; use std::cmp::max; use std::convert::{TryFrom, TryInto}; @@ -37,8 +37,7 @@ pub(crate) fn compute_host_function_transaction_data_and_min_fee( bucket_list_size: u64, current_ledger_seq: u32, ) -> Result<(SorobanTransactionData, i64)> { - let ledger_changes = - get_ledger_changes(budget, post_storage, pre_storage, ExpirationEntryMap::new())?; + let ledger_changes = get_ledger_changes(budget, post_storage, pre_storage, TtlEntryMap::new())?; let soroban_resources = calculate_host_function_soroban_resources(&ledger_changes, &post_storage.footprint, budget) .context("cannot compute host function resources")?; @@ -112,7 +111,7 @@ fn estimate_max_transaction_size_for_operation( read_bytes: 0, write_bytes: 0, }, - refundable_fee: 0, + resource_fee: 0, ext: ExtensionPoint::V0, }), }, @@ -137,10 +136,7 @@ fn calculate_host_function_soroban_resources( let read_bytes: u32 = ledger_changes .iter() .map(|c| { - c.old_entry_size_bytes - + c.expiration_change - .as_ref() - .map_or(0, |_| EXPIRATION_ENTRY_SIZE) + c.old_entry_size_bytes + c.ttl_change.as_ref().map_or(0, |_| EXPIRATION_ENTRY_SIZE) }) .sum(); @@ -196,10 +192,10 @@ fn get_fee_configurations( bail!("unexpected config setting entry for BandwidthV0 key"); }; - let ConfigSettingEntry::StateExpiration(state_expiration) = - ledger_storage.get_configuration_setting(ConfigSettingId::StateExpiration)? + let ConfigSettingEntry::StateArchival(state_expiration) = + ledger_storage.get_configuration_setting(ConfigSettingId::StateArchival)? else { - bail!("unexpected config setting entry for StateExpiration key"); + bail!("unexpected config setting entry for StateArchival key"); }; let write_fee_configuration = WriteFeeConfiguration { @@ -303,29 +299,27 @@ fn finalize_transaction_data_and_min_fee( let (non_refundable_fee, refundable_fee) = compute_transaction_resource_fee(transaction_resources, &fee_configuration); let rent_fee = compute_rent_fee(&rent_changes, &rent_fee_configuration, current_ledger_seq); + let resource_fee = refundable_fee + non_refundable_fee + rent_fee; let transaction_data = SorobanTransactionData { resources: soroban_resources, - refundable_fee: refundable_fee + rent_fee, + resource_fee, ext: ExtensionPoint::V0, }; - let res = ( - transaction_data, - refundable_fee + non_refundable_fee + rent_fee, - ); + let res = (transaction_data, resource_fee); Ok(res) } -pub(crate) fn compute_bump_footprint_exp_transaction_data_and_min_fee( +pub(crate) fn compute_extend_footprint_ttl_transaction_data_and_min_fee( footprint: LedgerFootprint, - ledgers_to_expire: u32, + extend_to: u32, ledger_storage: &LedgerStorage, bucket_list_size: u64, current_ledger_seq: u32, ) -> Result<(SorobanTransactionData, i64)> { - let rent_changes = compute_bump_footprint_rent_changes( + let rent_changes = compute_extend_footprint_rent_changes( &footprint, ledger_storage, - ledgers_to_expire, + extend_to, current_ledger_seq, ) .context("cannot compute bump rent changes")?; @@ -346,9 +340,9 @@ pub(crate) fn compute_bump_footprint_exp_transaction_data_and_min_fee( write_bytes: 0, }; let transaction_size_bytes = estimate_max_transaction_size_for_operation( - &OperationBody::BumpFootprintExpiration(BumpFootprintExpirationOp { + &OperationBody::ExtendFootprintTtl(ExtendFootprintTtlOp { ext: ExtensionPoint::V0, - ledgers_to_expire, + extend_to, }), &soroban_resources.footprint, ) @@ -372,26 +366,26 @@ pub(crate) fn compute_bump_footprint_exp_transaction_data_and_min_fee( ) } -fn compute_bump_footprint_rent_changes( +fn compute_extend_footprint_rent_changes( footprint: &LedgerFootprint, ledger_storage: &LedgerStorage, - ledgers_to_expire: u32, + extend_to: u32, current_ledger_seq: u32, ) -> Result> { let mut rent_changes: Vec = Vec::with_capacity(footprint.read_only.len()); for key in (&footprint).read_only.as_vec() { - let unmodified_entry_and_expiration = ledger_storage + let unmodified_entry_and_ttl = ledger_storage .get(key, false) .with_context(|| format!("cannot find bump footprint ledger entry with key {key:?}"))?; - let size = (key.to_xdr()?.len() + unmodified_entry_and_expiration.0.to_xdr()?.len()) as u32; - let expirable_entry: Box = (&unmodified_entry_and_expiration) + let size = (key.to_xdr()?.len() + unmodified_entry_and_ttl.0.to_xdr()?.len()) as u32; + let expirable_entry: Box = (&unmodified_entry_and_ttl) .try_into() .map_err(|e: String| { Error::msg(e.clone()).context("incorrect ledger entry type in footprint") })?; - let new_expiration_ledger = current_ledger_seq + ledgers_to_expire; - if new_expiration_ledger <= expirable_entry.expiration_ledger_seq() { + let new_live_until_ledger = current_ledger_seq + extend_to; + if new_live_until_ledger <= expirable_entry.live_until_ledger_seq() { // The bump would be ineffective continue; } @@ -399,8 +393,8 @@ fn compute_bump_footprint_rent_changes( is_persistent: expirable_entry.durability() == Persistent, old_size_bytes: size, new_size_bytes: size, - old_expiration_ledger: expirable_entry.expiration_ledger_seq(), - new_expiration_ledger, + old_live_until_ledger: expirable_entry.live_until_ledger_seq(), + new_live_until_ledger, }; rent_changes.push(rent_change); } @@ -413,15 +407,15 @@ pub(crate) fn compute_restore_footprint_transaction_data_and_min_fee( bucket_list_size: u64, current_ledger_seq: u32, ) -> Result<(SorobanTransactionData, i64)> { - let ConfigSettingEntry::StateExpiration(state_expiration) = - ledger_storage.get_configuration_setting(ConfigSettingId::StateExpiration)? + let ConfigSettingEntry::StateArchival(state_archival) = + ledger_storage.get_configuration_setting(ConfigSettingId::StateArchival)? else { - bail!("unexpected config setting entry for StateExpiration key"); + bail!("unexpected config setting entry for StateArchival key"); }; let rent_changes = compute_restore_footprint_rent_changes( &footprint, ledger_storage, - state_expiration.min_persistent_entry_expiration, + state_archival.min_persistent_ttl, current_ledger_seq, ) .context("cannot compute restore rent changes")?; @@ -468,7 +462,7 @@ pub(crate) fn compute_restore_footprint_transaction_data_and_min_fee( fn compute_restore_footprint_rent_changes( footprint: &LedgerFootprint, ledger_storage: &LedgerStorage, - min_persistent_entry_expiration: u32, + min_persistent_ttl: u32, current_ledger_seq: u32, ) -> Result> { let mut rent_changes: Vec = @@ -478,7 +472,7 @@ fn compute_restore_footprint_rent_changes( format!("cannot find restore footprint ledger entry with key {key:?}") })?; let size = (key.to_xdr()?.len() + unmodified_entry_and_expiration.0.to_xdr()?.len()) as u32; - let expirable_entry: Box = (&unmodified_entry_and_expiration) + let expirable_entry: Box = (&unmodified_entry_and_expiration) .try_into() .map_err(|e: String| { Error::msg(e.clone()).context("incorrect ledger entry type in footprint") @@ -487,18 +481,18 @@ fn compute_restore_footprint_rent_changes( expirable_entry.durability() == Persistent, "non-persistent entry in footprint: key = {key:?}" ); - if !expirable_entry.has_expired(current_ledger_seq) { - // noop (the entry hadn't expired) + if expirable_entry.is_live(current_ledger_seq) { + // noop (the entry is alive) continue; } - let new_expiration_ledger = - get_restored_ledger_sequence(current_ledger_seq, min_persistent_entry_expiration); + let new_live_until_ledger = + get_restored_ledger_sequence(current_ledger_seq, min_persistent_ttl); let rent_change = LedgerEntryRentChange { is_persistent: true, old_size_bytes: 0, new_size_bytes: size, - old_expiration_ledger: 0, - new_expiration_ledger, + old_live_until_ledger: 0, + new_live_until_ledger, }; rent_changes.push(rent_change); } diff --git a/cmd/soroban-rpc/lib/preflight/src/ledger_storage.rs b/cmd/soroban-rpc/lib/preflight/src/ledger_storage.rs index b000994c9..61d847780 100644 --- a/cmd/soroban-rpc/lib/preflight/src/ledger_storage.rs +++ b/cmd/soroban-rpc/lib/preflight/src/ledger_storage.rs @@ -2,12 +2,12 @@ use sha2::Digest; use soroban_env_host::storage::SnapshotSource; use soroban_env_host::xdr::ContractDataDurability::{Persistent, Temporary}; use soroban_env_host::xdr::{ - ConfigSettingEntry, ConfigSettingId, Error as XdrError, ExpirationEntry, Hash, LedgerEntry, - LedgerEntryData, LedgerKey, LedgerKeyConfigSetting, LedgerKeyExpiration, ReadXdr, ScError, - ScErrorCode, WriteXdr, + ConfigSettingEntry, ConfigSettingId, Error as XdrError, Hash, LedgerEntry, LedgerEntryData, + LedgerKey, LedgerKeyConfigSetting, LedgerKeyTtl, ReadXdr, ScError, ScErrorCode, TtlEntry, + WriteXdr, }; use soroban_env_host::HostError; -use state_expiration::{get_restored_ledger_sequence, has_expired, ExpirableLedgerEntry}; +use state_ttl::{get_restored_ledger_sequence, is_live, TTLLedgerEntry}; use std::cell::RefCell; use std::collections::HashSet; use std::convert::TryInto; @@ -28,8 +28,8 @@ extern "C" { pub(crate) enum Error { #[error("not found")] NotFound, - #[error("entry expired")] - EntryExpired, + #[error("entry is not live")] + NotLive, #[error("xdr processing error: {0}")] Xdr(#[from] XdrError), #[error("nul error: {0}")] @@ -45,9 +45,7 @@ pub(crate) enum Error { impl From for HostError { fn from(value: Error) -> Self { match value { - Error::NotFound | Error::EntryExpired => { - ScError::Storage(ScErrorCode::MissingValue).into() - } + Error::NotFound | Error::NotLive => ScError::Storage(ScErrorCode::MissingValue).into(), Error::Xdr(_) => ScError::Value(ScErrorCode::InvalidInput).into(), _ => ScError::Context(ScErrorCode::InternalError).into(), } @@ -55,7 +53,7 @@ impl From for HostError { } struct EntryRestoreTracker { - min_persistent_entry_expiration: u32, + min_persistent_ttl: u32, // RefCell is needed to mutate the hashset inside SnapshotSource::get(), which is an immutable method ledger_keys_requiring_restore: RefCell>, } @@ -68,7 +66,7 @@ impl EntryRestoreTracker { key: &LedgerKey, entry_and_expiration: &(LedgerEntry, Option), ) -> Option { - let expirable_entry: Box = match entry_and_expiration.try_into() { + let expirable_entry: Box = match entry_and_expiration.try_into() { Ok(e) => e, Err(_) => { // Nothing to track, the entry isn't expirable @@ -76,18 +74,18 @@ impl EntryRestoreTracker { } }; if expirable_entry.durability() != Persistent - || !expirable_entry.has_expired(current_ledger_sequence) + || expirable_entry.is_live(current_ledger_sequence) { // Nothing to track, the entry isn't persistent (and thus not restorable) or - // it hasn't expired - return Some(expirable_entry.expiration_ledger_seq()); + // it is alive + return Some(expirable_entry.live_until_ledger_seq()); } self.ledger_keys_requiring_restore .borrow_mut() .insert(key.clone()); Some(get_restored_ledger_sequence( current_ledger_sequence, - self.min_persistent_entry_expiration, + self.min_persistent_ttl, )) } } @@ -117,8 +115,8 @@ impl LedgerStorage { current_ledger_sequence, restore_tracker: None, }; - let setting_id = ConfigSettingId::StateExpiration; - let ConfigSettingEntry::StateExpiration(state_expiration) = + let setting_id = ConfigSettingId::StateArchival; + let ConfigSettingEntry::StateArchival(state_archival) = ledger_storage.get_configuration_setting(setting_id)? else { return Err(Error::UnexpectedConfigLedgerEntry { @@ -128,7 +126,7 @@ impl LedgerStorage { // Now that we have the state expiration config, we can build the tracker ledger_storage.restore_tracker = Some(EntryRestoreTracker { ledger_keys_requiring_restore: RefCell::new(HashSet::new()), - min_persistent_entry_expiration: state_expiration.min_persistent_entry_expiration, + min_persistent_ttl: state_archival.min_persistent_ttl, }); Ok(ledger_storage) } @@ -151,52 +149,56 @@ impl LedgerStorage { pub(crate) fn get( &self, key: &LedgerKey, - include_expired: bool, + include_not_live: bool, ) -> Result<(LedgerEntry, Option), Error> { let mut key_xdr = key.to_xdr()?; let xdr = self.get_xdr_internal(&mut key_xdr)?; - let expiration_seq = match key { + let live_until_ledger_seq = match key { // TODO: it would probably be more efficient to do all of this in the Go side // (e.g. it would allow us to query multiple entries at once) LedgerKey::ContractData(_) | LedgerKey::ContractCode(_) => { let key_hash: [u8; 32] = sha2::Sha256::digest(key_xdr).into(); - let expiration_key = LedgerKey::Expiration(LedgerKeyExpiration { + let ttl_key = LedgerKey::Ttl(LedgerKeyTtl { key_hash: Hash(key_hash), }); - let mut expiration_key_xdr = expiration_key.to_xdr()?; - let expiration_entry_xdr = self.get_xdr_internal(&mut expiration_key_xdr)?; - let expiration_entry = LedgerEntry::from_xdr(expiration_entry_xdr)?; - if let LedgerEntryData::Expiration(ExpirationEntry { - expiration_ledger_seq, + let mut ttl_key_xdr = ttl_key.to_xdr()?; + let ttl_entry_xdr = self.get_xdr_internal(&mut ttl_key_xdr)?; + let ttl_entry = LedgerEntry::from_xdr(ttl_entry_xdr)?; + if let LedgerEntryData::Ttl(TtlEntry { + live_until_ledger_seq, .. - }) = expiration_entry.data + }) = ttl_entry.data { - Some(expiration_ledger_seq) + Some(live_until_ledger_seq) } else { return Err(Error::UnexpectedLedgerEntryTypeForExpirationKey { - ledger_entry_type: expiration_entry.data.name().to_string(), + ledger_entry_type: ttl_entry.data.name().to_string(), }); } } _ => None, }; - if !include_expired - && expiration_seq.is_some() - && has_expired(expiration_seq.unwrap(), self.current_ledger_sequence) + if !include_not_live + && live_until_ledger_seq.is_some() + && !is_live(live_until_ledger_seq.unwrap(), self.current_ledger_sequence) { - return Err(Error::EntryExpired); + return Err(Error::NotLive); } let entry = LedgerEntry::from_xdr(xdr)?; - Ok((entry, expiration_seq)) + Ok((entry, live_until_ledger_seq)) } - pub(crate) fn get_xdr(&self, key: &LedgerKey, include_expired: bool) -> Result, Error> { + pub(crate) fn get_xdr( + &self, + key: &LedgerKey, + include_not_live: bool, + ) -> Result, Error> { // TODO: this can be optimized since for entry types other than ContractCode/ContractData, // they don't need to be deserialized and serialized again - let (entry, _) = self.get(key, include_expired)?; + let (entry, _) = self.get(key, include_not_live)?; Ok(entry.to_xdr()?) } @@ -235,12 +237,12 @@ impl SnapshotSource for LedgerStorage { let mut entry_and_expiration = self.get(key, true)?; // Explicitly discard temporary expired entries if let Ok(expirable_entry) = - TryInto::>::try_into(&entry_and_expiration) + TryInto::>::try_into(&entry_and_expiration) { if expirable_entry.durability() == Temporary - && expirable_entry.has_expired(self.current_ledger_sequence) + && !expirable_entry.is_live(self.current_ledger_sequence) { - return Err(HostError::from(Error::EntryExpired)); + return Err(HostError::from(Error::NotLive)); } } // If the entry expired, we modify the expiration to make it seem like it was restored diff --git a/cmd/soroban-rpc/lib/preflight/src/lib.rs b/cmd/soroban-rpc/lib/preflight/src/lib.rs index 4df90fb64..4354ae24d 100644 --- a/cmd/soroban-rpc/lib/preflight/src/lib.rs +++ b/cmd/soroban-rpc/lib/preflight/src/lib.rs @@ -1,7 +1,7 @@ mod fees; mod ledger_storage; mod preflight; -mod state_expiration; +mod state_ttl; extern crate anyhow; extern crate base64; @@ -30,9 +30,9 @@ pub struct CLedgerInfo { pub timestamp: u64, pub network_passphrase: *const libc::c_char, pub base_reserve: u32, - pub min_temp_entry_expiration: u32, - pub min_persistent_entry_expiration: u32, - pub max_entry_expiration: u32, + pub min_temp_entry_ttl: u32, + pub min_persistent_entry_ttl: u32, + pub max_entry_ttl: u32, } impl From for LedgerInfo { @@ -44,9 +44,9 @@ impl From for LedgerInfo { timestamp: c.timestamp, network_id: Sha256::digest(network_passphrase).into(), base_reserve: c.base_reserve, - min_temp_entry_expiration: c.min_temp_entry_expiration, - min_persistent_entry_expiration: c.min_persistent_entry_expiration, - max_entry_expiration: c.max_entry_expiration, + min_temp_entry_ttl: c.min_temp_entry_ttl, + min_persistent_entry_ttl: c.min_persistent_entry_ttl, + max_entry_ttl: c.max_entry_ttl, } } } @@ -167,7 +167,7 @@ fn preflight_invoke_hf_op_or_maybe_panic( } #[no_mangle] -pub extern "C" fn preflight_footprint_expiration_op( +pub extern "C" fn preflight_footprint_ttl_op( handle: libc::uintptr_t, // Go Handle to forward to SnapshotSourceGet and SnapshotSourceHas bucket_list_size: u64, // Bucket list size for current ledger op_body: CXDR, // OperationBody XDR @@ -175,7 +175,7 @@ pub extern "C" fn preflight_footprint_expiration_op( current_ledger_seq: u32, ) -> *mut CPreflightResult { catch_preflight_panic(Box::new(move || { - preflight_footprint_expiration_op_or_maybe_panic( + preflight_footprint_ttl_op_or_maybe_panic( handle, bucket_list_size, op_body, @@ -185,7 +185,7 @@ pub extern "C" fn preflight_footprint_expiration_op( })) } -fn preflight_footprint_expiration_op_or_maybe_panic( +fn preflight_footprint_ttl_op_or_maybe_panic( handle: libc::uintptr_t, bucket_list_size: u64, op_body: CXDR, @@ -195,7 +195,7 @@ fn preflight_footprint_expiration_op_or_maybe_panic( let op_body = OperationBody::from_xdr(from_c_xdr(op_body)).unwrap(); let footprint = LedgerFootprint::from_xdr(from_c_xdr(footprint)).unwrap(); let ledger_storage = &LedgerStorage::new(handle, current_ledger_seq); - let result = preflight::preflight_footprint_expiration_op( + let result = preflight::preflight_footprint_ttl_op( ledger_storage, bucket_list_size, op_body, diff --git a/cmd/soroban-rpc/lib/preflight/src/preflight.rs b/cmd/soroban-rpc/lib/preflight/src/preflight.rs index 6071f977f..d8b646c44 100644 --- a/cmd/soroban-rpc/lib/preflight/src/preflight.rs +++ b/cmd/soroban-rpc/lib/preflight/src/preflight.rs @@ -239,7 +239,7 @@ fn get_budget_from_network_config_params(ledger_storage: &LedgerStorage) -> Resu Ok(budget) } -pub(crate) fn preflight_footprint_expiration_op( +pub(crate) fn preflight_footprint_ttl_op( ledger_storage: &LedgerStorage, bucket_list_size: u64, op_body: OperationBody, @@ -247,9 +247,9 @@ pub(crate) fn preflight_footprint_expiration_op( current_ledger_seq: u32, ) -> Result { match op_body { - OperationBody::BumpFootprintExpiration(op) => preflight_bump_footprint_expiration( + OperationBody::ExtendFootprintTtl(op) => preflight_extend_footprint_ttl( footprint, - op.ledgers_to_expire, + op.extend_to, ledger_storage, bucket_list_size, current_ledger_seq, @@ -267,17 +267,17 @@ pub(crate) fn preflight_footprint_expiration_op( } } -fn preflight_bump_footprint_expiration( +fn preflight_extend_footprint_ttl( footprint: LedgerFootprint, - ledgers_to_expire: u32, + extend_to: u32, ledger_storage: &LedgerStorage, bucket_list_size: u64, current_ledger_seq: u32, ) -> Result { let (transaction_data, min_fee) = - fees::compute_bump_footprint_exp_transaction_data_and_min_fee( + fees::compute_extend_footprint_ttl_transaction_data_and_min_fee( footprint, - ledgers_to_expire, + extend_to, ledger_storage, bucket_list_size, current_ledger_seq, diff --git a/cmd/soroban-rpc/lib/preflight/src/state_expiration.rs b/cmd/soroban-rpc/lib/preflight/src/state_expiration.rs deleted file mode 100644 index d0c9bbff1..000000000 --- a/cmd/soroban-rpc/lib/preflight/src/state_expiration.rs +++ /dev/null @@ -1,70 +0,0 @@ -use soroban_env_host::xdr::ContractDataDurability::Persistent; -use soroban_env_host::xdr::{ - ContractCodeEntry, ContractDataDurability, ContractDataEntry, LedgerEntry, LedgerEntryData, -}; -use std::convert::TryInto; - -pub(crate) trait ExpirableLedgerEntry { - fn durability(&self) -> ContractDataDurability; - fn expiration_ledger_seq(&self) -> u32; - fn has_expired(&self, current_ledger_seq: u32) -> bool { - has_expired(self.expiration_ledger_seq(), current_ledger_seq) - } -} - -impl ExpirableLedgerEntry for (&ContractCodeEntry, u32) { - fn durability(&self) -> ContractDataDurability { - Persistent - } - - fn expiration_ledger_seq(&self) -> u32 { - self.1 - } -} - -impl ExpirableLedgerEntry for (&ContractDataEntry, u32) { - fn durability(&self) -> ContractDataDurability { - self.0.durability - } - - fn expiration_ledger_seq(&self) -> u32 { - self.1 - } -} - -// Convert a ledger entry and its expiration into an ExpirableLedgerEntry -impl<'a> TryInto> for &'a (LedgerEntry, Option) { - type Error = String; - - fn try_into(self) -> Result, Self::Error> { - match (&self.0.data, self.1) { - (LedgerEntryData::ContractData(d), Some(expiration_seq)) => { - Ok(Box::new((d, expiration_seq))) - } - (LedgerEntryData::ContractCode(c), Some(expiration_seq)) => { - Ok(Box::new((c, expiration_seq))) - } - (LedgerEntryData::ContractData(_) | LedgerEntryData::ContractCode(_), _) => { - Err(format!( - "missing expiration for expirable ledger entry ({})", - self.0.data.name() - )) - } - _ => Err(format!( - "ledger entry type ({}) is not expirable", - self.0.data.name() - )), - } - } -} - -pub(crate) fn has_expired(expiration_ledger_seq: u32, current_ledger_seq: u32) -> bool { - current_ledger_seq > expiration_ledger_seq -} - -pub(crate) fn get_restored_ledger_sequence( - current_ledger_seq: u32, - min_persistent_entry_expiration: u32, -) -> u32 { - return current_ledger_seq + min_persistent_entry_expiration - 1; -} diff --git a/cmd/soroban-rpc/lib/preflight/src/state_ttl.rs b/cmd/soroban-rpc/lib/preflight/src/state_ttl.rs new file mode 100644 index 000000000..0a3fbab88 --- /dev/null +++ b/cmd/soroban-rpc/lib/preflight/src/state_ttl.rs @@ -0,0 +1,67 @@ +use soroban_env_host::xdr::ContractDataDurability::Persistent; +use soroban_env_host::xdr::{ + ContractCodeEntry, ContractDataDurability, ContractDataEntry, LedgerEntry, LedgerEntryData, +}; +use std::convert::TryInto; + +pub(crate) trait TTLLedgerEntry { + fn durability(&self) -> ContractDataDurability; + fn live_until_ledger_seq(&self) -> u32; + fn is_live(&self, current_ledger_seq: u32) -> bool { + is_live(self.live_until_ledger_seq(), current_ledger_seq) + } +} + +impl TTLLedgerEntry for (&ContractCodeEntry, u32) { + fn durability(&self) -> ContractDataDurability { + Persistent + } + + fn live_until_ledger_seq(&self) -> u32 { + self.1 + } +} + +impl TTLLedgerEntry for (&ContractDataEntry, u32) { + fn durability(&self) -> ContractDataDurability { + self.0.durability + } + + fn live_until_ledger_seq(&self) -> u32 { + self.1 + } +} + +// Convert a ledger entry and its Time to live (i.e. live_until_seq) into a TTLLedgerEntry +impl<'a> TryInto> for &'a (LedgerEntry, Option) { + type Error = String; + + fn try_into(self) -> Result, Self::Error> { + match (&self.0.data, self.1) { + (LedgerEntryData::ContractData(d), Some(live_until_seq)) => { + Ok(Box::new((d, live_until_seq))) + } + (LedgerEntryData::ContractCode(c), Some(live_until_seq)) => { + Ok(Box::new((c, live_until_seq))) + } + (LedgerEntryData::ContractData(_) | LedgerEntryData::ContractCode(_), _) => Err( + format!("missing ttl for ledger entry ({})", self.0.data.name()), + ), + _ => Err(format!( + "ledger entry type ({}) cannot have a TTL", + self.0.data.name() + )), + } + } +} + +pub(crate) fn is_live(expiration_ledger_seq: u32, current_ledger_seq: u32) -> bool { + current_ledger_seq <= expiration_ledger_seq +} + +pub(crate) fn get_restored_ledger_sequence( + current_ledger_seq: u32, + min_persistent_entry_expiration: u32, +) -> u32 { + return current_ledger_seq + min_persistent_entry_expiration - 1; +}