#State Expiration Naming

207 messages · Page 1 of 1 (latest)

thin mirage
#

Coming off of Meridian, it seems like the name "state expiration" comes across negatively and leads to some misconceptions regarding what state expiration actually is. In particular, people are concerned with permanently losing data and ledger immutability when they first hear "state expiration." Before the XDR is finalized at the end of the week, I think it's worth revisiting state expiration naming. Ideally, this new name would better indicate that:

  1. Expired entries are not permanently "lost", but can be restored and used again
  2. Ledger state is still immutable. When an entry is evicted, it leaves behind a cryptographic "fingerprint" maintaining ledger immutability.

With this is mind, I think we should revisit the following terms:
State Expiration
The names of the states themselves (LIVE, EXPIRED, and EVICTED)
Expired State Store (ESS)
What we define as "the ledger"

Previously, "the ledger" has referred to the state that is currently stored on the validator's DB. This means that whenever an entry expires, it is deleted from the validator DB and therefore "deleted from the ledger." I think we should change this so that "the ledger" encompasses all entries, both those that are live and stored on the validator as well as those that are expired and no longer stored on the validator. When an entry expires, it's position is moved and it cannot be immediately used, but "ledger state" remains unchanged.

With this in mind, one suggestion is to change the terms "LIVE and EXPIRED" to "ACTIVE and INACTIVE". We can say that validators store a local cache of "ACTIVE" entries. In order to stay in this cache and have fast, immediate access to a given entry, you must pay the rent fee to remain "ACTIVE". If you don't pay this fee, the entry becomes "INACTIVE" and is evicted from the cache. It can still be used if it's made active again, but this is a slower and more expensive process because the entry is no longer in the cache.

#

I think the cache based language will be easier to understand for developers and actually better describes what state expiration is, a tiered cache system for ledger state. This should also alleviate ledger immutability concerns, as state is never "deleted" from the ledger, it's just evicted from a cache. We could call the ESS soemthing like "Inactive State Store". We could rename state expiration to "Ledger state caching". We can shift the focus away from deleting state. Instead, this would be an optimization, where frequently used data becomes faster to access and validators and history production become more effecient because of the cache. What are your thoughts on these names? Open to feedback or suggestions for other names as well.

wintry horizon
#

Yeah I do feel there is definitely a negative connotation attached to the word 'expiration'. maybe a more proper word will be 'state dispersion'. Eh? just an idea

desert quiver
#

For clarity - the final states are (ACTIVE, INACTIVE, and EVICTED), yeah?

Since "State Caching" has gone through a few implementations, can you clarify the seperation between INACTIVE and EVICTED? It sounds like the change to EVICTION occurs when the entry is removed from ledger validator DB to the "yearly" merkle tree that still lives on validators.

Lastly, COLD might be a nicer word than EVICTED that gets roughly the same idea across in the caching analogy, but does have the downside of having a crypto usage already.

gritty stone
#

I like how ESS becomes ISS

thin mirage
#

Yeah, I like cold. The states would be ACTIVE, INACTIVE, and COLD. An entry starts as ACTIVE, and becomes INACTIVE when rent payments stop. When an entry is deleted from the validator DB and sent to the (On validator) merkle Tree, it is considered COLD.

#

Similarly to what we do now, we wouldn't really distinguish between the INACTIVE and COLD states for end users.

desert quiver
#

My only concern with this is there is (for me) some confusion on where the data actually lives.

  1. Active -> always in DB on validator
  2. Inactive -> always in DB on validator
  3. Cold -> on merkly tree in validator OR on merkle tree on a ISS (which, while a fun space name, is a bit weird seeing as it does not hold inactive ledger entries)
thin mirage
#

I think this also aligns with the usage of cold in other Blockchain contexts too. Like if you're wallet is a cold store, why not have the balance itself be in the COLD store on-cahin

gritty stone
#

we've tried to get rid of evicted/expired dichotomy. it is useful in some contexts, but we need one term for all the entries that are not immediately available ('inactive' should work)

thin mirage
gritty stone
#

maybe 'inactive, still in DB' and 'inactive, in ISS' would make more sense

#

so ISS still makes sense and this is more of a fine detail that is mostly irrelevant

desert quiver
#

Would:

  1. Inactive -> needs restoration proof
  2. Cold -> inactive and not on validator
    work?
gritty stone
#

hmm, 1 doesn't exist. if entry happens to be on validator, we can restore it without proofs

thin mirage
#

I like the idea of cold, but I think it makes more sense actually to go with active, inactive, and evicted, where the types exposed to the end user are just active and inactive

#

Internally, the types mean:
Active: in DB, can be used
Inactive: in DB, must be restored
Evicted: not in DB, must be restored

#

The user doesn't care where data lives, so the end user interface becomes:
Active: can be used
Inactive: needs to be restored

gritty stone
#

I would prefer explicit subtyping

#

i.e. on layer one there is only Active/Inactive, and then inactive may be in db or not in db.

#

otherwise 'inactive' might mean different things in different contexts

thin mirage
#

Sure, we can figure out subtypes later. For now we just need to define active and inactive, we can decide on subtype naming later when we have a clearer view of the ISS

gritty stone
#

yeah, that's fine.

thin mirage
#

So are we good with the following?

State Expiration -> State Caching
LIVE -> ACTIVE
EXPIRED -> INACTIVE
Expired State Store (ESS) -> Inactive State Store (ISS)
"ledger" refers to both ACTIVE and INACTIVE state
lifetime stays the same
rent stays the same

prisma zealot
#

I'm just going to toss my 2 cents in here that I'd also love to revisit the "watermark" terminology in bumping. Not sure if that is relevant to this or just the SDK though. That term is confusing and I'm still not sure I fully understand it

thin mirage
#

Sure, I think we need to keep the functionality as is, but we can play with the naming and the exposed interface. We need something like "If lifetime below x, bump to y", what naming/function interface do you think would be easier to understand?

#

Also, for op names, I think we can keep lifetime extension as is, but what about restore? Should we change this to something like "activate" or "reactivate"? At first glance it sounds a little weird tbh

desert quiver
normal hamlet
#

For the cold/evicted state I think the term "archived" is natural, but we avoided it in the past since stellar archives are already a thing. Maybe overloading the term wouldn't be that confusing given that most developers don't interact with archives.

pliant epoch
#

I think naming is only one part of the concern around the state expiration mechanism.

I understand the fingerprint concept to prevent fake data reappearing on-chain. However, I think it's important to note that we don't yet have any design for the ESS/ISS. So some of the concern about ledger mutability is valid IMO because there is no proposal (yet) around how to reliably preserve this data off-chain. For example, what guarantees can a user expect for storage retention of the off-chain data? That is fundamentally different from a caching problem.

gritty stone
#

I mean, someone would need to maintain ISS, similar to how someone maintains validators. I'm not sure if that's a design question necessarily.

pliant epoch
#

I'm not sure if that's a design question necessarily.

@thin mirage proposes ledger redefinition:

"the ledger" encompasses all entries, both those that are live and stored on the validator as well as those that are expired and no longer stored on the validator.

The current definition provides me, as a user, with some strong guarantees about my data.

  1. My data is co-located with stellar-core, and replicated 100% on every validator.
  2. My data has the same guarantees as the network itself. The network would need to lose safety before my data could be modified.
  3. To delete my data entirely, the state of the blockchain would have to be compromised.

The proposed new definition is substantially different.

  1. My data can be moved off-chain to a new service, which is not the Stellar blockchain.
  2. My data still cannot be replaced with fake data, because of on-chain fingerprinting. To modify the fingerprint requires loss of network safety.
  3. To delete my data entirely, it suffices for the (unknown) off-chain store to disappear or be compromised (corrupted data can't be reloaded to the network).

So my point is: this is a quite different set of assumptions. Since the off-chain store is not defined, we can have no expectations (yet) around resilience to attack; level of decentralisation; Byzantine failure etc.

gritty stone
#

sure, but this definition is independent of the design details, isn't it? it's an explicit requirement - if the data is not maintained as a part of the active chain state by the validators (which is the purpose of the state expiration), it has to be maintained separately. so if we're not fine with that, I don't think there exists some magic solution that would change this fundamental requirement.

pliant epoch
#

so if we're not fine with that
I think all I'm saying is it is rational to not be fine with that, without some implementation proposal to inspect.

Another way to say this. We assert:

Expired entries are not permanently "lost", but can be restored and used again

But this claim cannot be evaluated (yet), since there is no design to inspect.

Another way to say this. We assert:

In particular, people are concerned with permanently losing data and ledger immutability

Rationally, people should be happy with ledger immutability (nothing can be tampered with). Since there is no ISS/ESS design (yet), they should (currently) have reasonable concerns about permanently losing data.

gritty stone
#

history archives contain all the data necessary to restore the ledger state. of course, you can also be concerned that the archives are also deleted and the data is lost, but really someone has to store the data

cloud turtle
#

The current naming scheme makes sense from the system design standpoint. We should consider naming for the contract developer’s mental model, focusing on how might a dev think about data.

Suggestions:

  1. State Expiry renamed to Storage Lifecycle or Contract Data Lifecycle
    Explanation: the data transitions through various states, each requiring careful management.

  2. Live renamed to Accessible, Readable, or Fetchable
    Explanation: data must be in this state to be read. If it’s not in this state, it cannot be read. So why not indicate readability with the name.

  3. Expired renamed to Inaccessible, Unreadable, or Stale
    Explanation: data in this state cannot be accessed by the developer without additional effort.

  4. Evicted renamed to Archived, Preserved, RequiresRefresh
    Explanation: data in this state cannot be easily read. To read, you must first “refresh”.

  5. The data has to be Restored / Renewed / Reloaded to become Accessible again.

  6. ESS renamed to Archive Storage or Cold Storage. (Amazon uses “Glacier” for the service that’s supposed to store archived data.)

Best not to use “delete” anywhere since it introduces uncertainty around ledger state and the ability to restore.

pliant epoch
#

Ok, I thought about this a bit more and there's a mistake in the logic I proposed.

The key point: even without ESS/ISS, no data is lost, because all data, including expired entries, can be (slowly) recovered from history archives with replay.

With that understood, everything is watertight.
You don't need reliability of ESS/ISS. It's just a convenience mechanism.
You don't need to trust ESS/ISS. You take what it gives you, and if it matches your fingerprint on-chain, you're good.
In fact, ESS/ISS as a general concept doesn't even need to exist. You could record data you care about locally and just put it back when you like.
So - nothing can be lost. Nothing can be tampered with.

I think this should be made explicit in our communications.
Sorry for the noise!

gritty stone
#

thanks for summarizing this!

queen thicket
#

Ideally the new name for "expired" (the middle state) gives a hint that it's on the way to the long term storage, so make those two other states somewhat related (so that there is a clear distinction between "live" and the other states). For example, from the list above, it could be "accessible -> freezing -> frozen" (which works with "cold storage" for the ESS -- that cannot be confused with "archives" that we already have today) ; or "accessible -> preserving -> preserved" (not sure if there is a good name for the ESS here)

normal hamlet
#

Conveniently freezing and frozen communicate the immutability.

cloud turtle
#

“Long term storage” is a great name, though it makes you question the durability of onchain data, which makes it a not-so-great name.

Cold Storage goes with the Freezing metaphor
Extended Storage
Historical Storage

iron grove
#

Will the history archive snapshots always be consistent with the validator db? In other words, if the validator db stores active and inactive ledger entries (but not evicted ledger entries) can we assume that the history archive snapshots will store the same data?

gritty stone
#

freezing -> frozen
again, this doesn't play well with a single term to use in the developer docs. I'd want to have just a single 'main' term and then 2 different terms to distinguish between 'in ledger' and 'in ISS' states.

thin mirage
# iron grove if we are renaming expired to inactive then Inactive State Store is a misleading...

I think I'd like to stick to just two state names for the purposes of naming, active and inactive. In the future when there's something like the ISS, we could have different sub-names for different types of inactive state. There's 3 different types of potential inactive state, so the term eviction doesn't seem appropriate either. The sub states are:
Inactive, in validator DB
Inactive, in validator merkle tree
Inactive, in ISS merkle tree

#

I'd like to abstract these states away from the end user in the ISS design and expose just the active vs inactive states

iron grove
#

from the end user perspective does it matter if an inactive ledger entry is in the validator db vs the validator merkle tree vs the ISS merkle tree? Is the procedure to recover the inactive ledger entry the same regardless of the inactive sub state?

gritty stone
#

depends on who the 'end user' is. ideally, the client-side restore interface was the same (e.g. just call some special RPC method). then from the RPC standpoint these states would be different.

normal hamlet
#

The time it takes to restore might be different.

thin mirage
#

Yeah interface isn't finalized or anything yet, but the goal is to make the process the same. It seems like a poor UX if we expose 3 different types of "restore" op depending on what sub state an entry is in, especially since eit will probably be somewhat difficult to determine what state an entry is in

gritty stone
#

exactly - it's perfectly fine to expose the state difference to the end user via e.g. 'restoration ETA' without using any special terms (just 'entry can already be restored' or 'wait for 10 minutes' etc.)

iron grove
gritty stone
#

that's not the core op, that would be e.g. an RPC call. core op wants entry to be immediately restorable (i.e. either still live on-chain or have the proof uploaded)

thin mirage
#

Yeah again this is all tbd since we haven't designed the proof submission interface, but I think having multiple restore ops that are user facing is unacceptable. I don't think the actual implementation details are super important for this conversation, but we definitely need a single entry point for restoration (whether that be an op, RPC endpoint, etc)

gritty stone
#

it's important to note that core can't be the entry point. it's a requirement that core can immediately execute any incoming operation. so in order to integrate with ISS a different service would need to be used.

#

the details are indeed TBD

fringe walrus
#

I know it might not be the best way to describe those that left the "cache" but when I was explaining it to my partner, I used the term "archived" and she got it right away as she understood is removed but not really lost, it was just moved to another place

dusty marlin
#

I was also just thinking of 'archived'

#

But wasn't sure on the 'in between' state yet, and also the acronym for Archived State Storage may need work

thin mirage
#

Ok so I think we've reached consensus on the following terms:
Use only two state names for now (i.e. active vs inactive)
The "ledger" contains all data, both active and inactive.

We still need to finalize the state names, state transition names, and the name of the project as a whole

zenith oracle
#

@thin mirage In the new terminology, do we still have a notion of permanent and temporary entries? In which case, these terms only apply to permanent entries and where temp entries can still be forever inactive (and non-restorable) correct? Going back to @pliant epoch earlier concern, if this is true, we still have a class of ledger data that is irrecoverable?

gritty stone
#

yes, temp entries are still there and they can only be either active or deleted

#

it is fine though, as they should be specifically used for temporary data, normally with an explicit lifetime boundary (e.g. nonces, token allowances etc.)

thin mirage
#

While archive is already a Stellar term, I've heard a lot of good feedback surrounding "archive" terminology. Additionally, we have the history archive and the ESS is essentially the "state" archive. Since we already have a history archive (which is a standard thing in most blockchains), adding a new type of archive, the state archive, might make sense and have less shock value to developers. With that in mind, I propose the following names:

Names
archive -> history archive
Archiver -> history archiver
state expiration -> state archiving
ESS -> state archiver

State names:
Live -> active
Expired -> archived
ledger -> all state, both active and archived

temporary and persistent stay the same
restore, lifetime, bump stay the same

#

The "archived" state will have several implementation specific sub-states that will not be exposed (in db, in validator merkle tree, in state archiver merkle tree)

cloud turtle
thin mirage
#

In protocol 20, costs the same as writing the entry, instant restore. Protocol 21+, TBD

normal hamlet
#

Isn't the archive already called the history archive today?

thin mirage
#

I think the full name is history archive, but we shorthand to "archive" pretty often. We'd need to make sure we consistently say "history archive"

normal hamlet
#

I like the name archive, althoguh it is harder to work into some sentences. For example, the function in the SDK that tells a developer what the max expiration is, is named max_expiration. It feels awkward to use archival terminology in places like this.

#

max_time_to_archive?

#

We could lean into TTL terminology, and keep the 'live' instead of 'active'. e.g. that function would be max_ttl.

#

And we'd say that when the TTL expires it is archived. This is sorta similar to DNS, where TTL doesn't mean something is gone, it's just no longer cached.

fringe walrus
#

what about using the "rent" terminology as the expiration like max_rent and let developers know that as soon as rent is out, it gets archived

normal hamlet
#

Basically changing how we talk about periods by their time to "live" rather than time to "expire." The latter is what we do now.

prisma zealot
#

I like the idea of leaning into ttl and borrowing from cache terminology

thin mirage
#

I like live, archived, and ttl

#

Perhaps we still use the term "lifetime" in docs like we're using it now, but in function headers and code, we replace expiration_ledger with ttl?

normal hamlet
#

I think it helps if the inactive state is called archived instad of expired. Much of the negative vocab comes from "expired" and not so much "live".

thin mirage
#

So revisiting the bump function, do we want do to something like threshold, ttl, where we bump up to ttl if current lifetime is below threshold? Threshold still feels a little vague, maybe something like min_threshold?

normal hamlet
#

bump(min_ttl, max_ttl)?

#

bump_ttl(min, max)?

#

update_ttl(min, max)?

#

I'm not sure "bump" terminology is doing much for us fwiw if we use a well understood term like TTL.

thin mirage
#

Maybe switch to "extend" instead of "bump"?

prisma zealot
#

set_ttl(min, max)

thin mirage
#

I'm not a huge fan of min,max, just because I'm not sure what min means in this context

#

Slight pushback against set, just because you can only increase it and set makes me think it can be set to an arbitrary value

normal hamlet
#

@thin mirage Is this doc read true?

/// Extend the TTL of the data to a value that is at least min and at most max.
pub fn extend_ttl(k: &K, min: u32, max: u32)
prisma zealot
#

Though I actually don't think that's how min works does it? Isn't min more a "increase by max if what's left before expiration is less than the min?"

thin mirage
#

I think we should remove on "max" terminology from the extend_ttl function, min is OK though

#

I like extend_ttl btw

normal hamlet
#
/// Extend the TTL if under the threshold.
pub fn extend_ttl(k: &K, threshold: u32, ttl: u32)
#

It's pretty easy to document and describe it, as you stated above ☝🏻

prisma zealot
#

under the threshold
Can I get a solid for instance here with some concrete values so my pea brain can ensure it understands these two values?

thin mirage
#

Consider extend_tll("key", 10, 100)

Case 1: key.ttl == 9
Current TTL is below threshold, so TTL is bumped.
Result: key.ttl == 100

Case 2: key.tll == 11
Current TTL is above theshold, so no bump occurs.
Result: key.ttl == 11

prisma zealot
#

That's very helpful thank you!
Also it doesn't bump by ttl it bumps to ttl
So in your case it is in fact 100 not 109

#

Also we probably shouldn't use ttl as that implies time 😛

#

ltl, ledgers to live

thin mirage
#

I think ledger is close enough to time, so I'm good with TTL personally

normal hamlet
#

Same, in Soroban there is no notion of time other than ledger.

#

Although outside Soroban Stellar txs do have time.

#

Actually not true, there is actual time in Soroban. I forgot, we expose close time.

prisma zealot
#

I think it'll be a little confusing as everywhere else in programming ttl refers to seconds

normal hamlet
#

At least it'd only be off by ~one magnitude.

prisma zealot
#

I think we could maybe stick with extend or even bump if we change the variable names to something like:
(
[threshold, wait, gap, tolerance]
[extend_by, number_of_ledgers, ledgers]
)

#

I feel like there's a word I'm looking for for that first argument that would really clear this up for folks

#

extend(extend_if, extend_by)

#

extend(threshold, ttl) may be fine

#

With proper inline comments I think it'll be clear enough

thin mirage
#

extend(threshold, extend_to)?

prisma zealot
#

extend(threshold, extend_max)? To implies a specific point or amount but my understanding is it will extend up to the max amount allowed by the network but that may be far below what you are asking it to extend to

gritty stone
#

Also it doesn't bump by ttl it bumps to ttl
that's not correct, we bump by ledgers

#

Case 1: key.ttl == 9
this example is rather confusing. there is no explicit TTL field and there can't be one. instead every LE has the expiration ledger, which is the last ledger (inclusive) when the entry is alive

#

here is the updated example:
Consider extend_tll("key", 10, 100), current ledger seq = 1000

Case 1: key.expiration_ledger == 1009 (TTL = 1009 - 1000 = 9)
Current TTL is below threshold, so TTL is bumped.
Result: key.expiration_ledger == 1000 + 100 - 1 == 1099 (-1 is an arbitrary implementation choice we've made)

Case 2: key.expiration_ledger == 1011 (TTL = 1011 - 1000 = 11)
Current TTL is above theshold, so no bump occurs.
Result: key.expiration_ledger == 1011

semantics is the same, but since dapp developers are likely to observe the expiration_ledger (or whatever we name it) it's useful to explain the behavior in terms of expiration ledger

normal hamlet
thin mirage
# normal hamlet extend(threshold, extend_by)?

I think I still prefer extend_to. extend_by indicates to me that the bump is additive. For example if extend_by == 10, I would expect the current TTL to be extend by 10 on every call, which is not the case

#

While Dima is right, technically we have an expirationLedger value and not a "lifetime/ttl" value, from the perspective of the contract itself, the entries essentially have a TTL like in my example. Personally I think it makes more sense to discuss bump host funcations in terms of TTL and not expirationLedger. Since contracts can't access the current ledger or the raw expirationLedger, it's essentially meaningless to discuss lifetimes in the context of contracts without using a TTL/lifetime interface. I'd expect dev tools like the CLI to "speak" in terms of lifetime instead of raw expirationLedger. While the underlying on-disk representation doesn't contain a true TTL, I feel like it's fine to have somewhat different interface given how much we limit what information the contract can actually access. My personal vote is still
extend(threshold, extend_to

gritty stone
#

Since contracts can't access the current ledger
they actually can

thin mirage
gritty stone
#

yeah, I'm ok with using TTL for the interface. just need to keep the docs fair and explain the expiration ledger implications (because, again, dapp developers will encounter expiration ledger)

cloud turtle
#

Could we summarize the final developer-facing interface and terminology plz? @thin mirage @gritty stone

queen thicket
thin mirage
#

TLDR:
Names
state expiration -> state archiving
ESS -> state archiver

State names:
Live -> live
Expired -> archived
ledger -> all state, both active and archived

temporary and persistent stay the same
restore stays the same
Lifetime -> ttl
Bump -> extend

For extend host functions:

bump(key, low_watermark, high_watermark)
->
extend(key, threshold, extend_to)

Where the semantics are the same as they were before, only the names have changed

hidden palm
#

Good idea 💡

prisma zealot
#

Still not a fan of extend_to and that implies it will extend the lifetime to that ledger but that isn’t true. That value is an extend the lifetime by that number of ledgers. Unless I’m misunderstanding something

gritty stone
#

agree

#

why not extend_by?

hidden palm
#

I dont fully understand the low,high argument for how many ledgers. But ya extend by seems to make more sense

fringe walrus
thin mirage
# prisma zealot Still not a fan of extend_to and that implies it will extend the lifetime to tha...

This is not correct, and part of the reason I still think extend_to is better. If an entry's current TTL is 6, and extend_to == 10, the result will be a TTL == 10 . At least in my reading, extend_by would imply that we add 10 ledgers to whatever the current TTL is, which is not the case. Rather, the TTL is set to the value specified by extend_to.

To reiterate:
suppose I call extend(key, threshold=5, extend_to=10)

if key.ttl == 6:
6 is above threshold, no bump occurs
result: key.ttl == 6

if key.ttl == 4
4 is below threshold, lifetime is extend to extend_to value
result: key.ttl == 10

gritty stone
#

hmm, also, did we actually call this extend? I thought it should be extend_ttl

#

then it would make more sense

thin mirage
#

Right now it's jsut extend, I agree I prefer extend_ttl

#

It might be too late for the actual host function (idk if XDR changes would be required or not or would be too disruptive to downstream at this point) but maybe we could change the SDK to extend_ttl?

prisma zealot
#

Is this how it will work or how it does work because in my experience with low watermark and high watermark, it does not behave this way

#

Right now I’m pretty sure high water mark adds that number of ledgers to the expiration versus setting the expiration ledger to the high number that you set

thin mirage
prisma zealot
#

The elusive and mysterious third option

gritty stone
#

It might be too late for the actual host function
not really, there is no downstream impact besides sdk. FWIW I recall leaving a comment about extend_ttl but maybe I have a false memory, lol

thin mirage
#

Internally, lifetime is managed by an absolute liveUntilLedger. For concurrency reasons, we can't expose this absolute ledger to smart contract. Instead, we expose a relative lifetime value called TTL. TTL is defined as

e.TTL == max(0, e.liveUntilLedger - currentLedger())

The current extend function reasons only in terms of TTL, not absolute ledger. If your extend_to value is 10, the TTL of the entry is set to 10. This is different than just adding extend_to ledgers to your current liveUntilLedgerSeq and is different han setting liveUntilLedgerSeq to extend_to ledgers, which are the two options you've listed

#

A full example is as follows:

prisma zealot
#

Keep in mind that the current functionality if you attempt to extend past the high watermark, you’ll get failures it doesn’t truncate or cap the high watermark it just fails. I know we had talked about that. Just keep that in mind.

gritty stone
#

btw we need to do some renames anyway - get_max_live_until_ledger is inconsistent with the new ttl naming

thin mirage
#

We call

extend(key, 5, 10)

Suppose currentLedger == 100
when key.liveUntilLedger == 104

let ttl = max(0, key.liveUntilLedger - currentLedger())
// ttl == 4

if ttl < threshold // if 4 < 5
    let new_live_until_ledger = currentLedger() + extend_to
    // new_live_until_ledger == 100 + 10 = 110
    key.liveUntilLedger = new_live_until_ledger

result: key.liveUntilLedger == 110

If we did this "high water mark adds that number of ledgers to the expiration", the result would be
key.liveUntilLedger += extend_to
key.liveUntilLedger == 114

If we did this "setting the expiration ledger to the high number that you set":
key.liveUntilLedger = extend_to
key.liveUntilLedger == 10

#

Due to the limitations of the interface, we have to reason in relative TTL terms. When you load the raw entry, you'll see an absolute liveUntilLedger. I'd recommend converting that to the relative TTL value via TTL == currentLedger - liveUntilLedger. Our CLI and SDK tools will be reasoning in terms of TTL, not absolute ledgers (if they are not already doing so)

gritty stone
#

I think TTL is actually more convenient - you're never really interested in absolute extensions unless you're creating a temp entry (at which point liveUntilLedger is equivalent to TTL)

#

hmm, but I'm still not sure about get_max_live_until_ledger... is that an official new term?

#

I guess it is, and the motivation is that you'd probably want this for checking things like max allowance lifetime... we could leave it as is, but also could change it to get_max_entry_ttl if we anticipate clamping to be more prevalent. probably not worth bothering though...

thin mirage
#

Ya that's correct, it will return the current maximum ledger value that you can set liveUntilLedgerSeq to. Idk if it's useful though, I'd much rather have it return the maximum relative value getMaxTTL. I think this would be the optimal design for max bump:

extend_ttl(key, 100, getMaxTTL())

Currently you have to convert it manually (or have the SDK do it)

let max_ttl = get_max_live_until_ledger() - get_current_ledger()
extend_ttl(key, 100, max_ttl)
#

+1 on get_max_entry_ttl() You can convert either form to the other, but I think max TTL will be used way more often than max absoluite liveUntilLedger

gritty stone
#

yeah, it's a bit hard to predict which one would be more useful, but I think at the very least we provide more value by using consistent terms. we could also add an example where we check for actual max expiration

prisma zealot
#

@desert quiver assuming you understand what’s being said here any thoughts on terminology?

hidden palm
#

ah so that conversation just enlightened me about if it was possible to query which ledger it would expire at 😄

#

i'm not sure i love the ttl naming in this case, even though it is pretty commonly used in the space... it seems like it could easily be mis-intrepred by a novice to mean time until it becomes live .

#

but it does help it become a bit more intuitive for me so it's probably good

#

On one hand, it's a well-established term in the tech space, making it instantly recognizable to those familiar with it. On the other hand, it could easily be misconstrued by newcomers to imply the time until the data becomes live, rather than its lifespan in the system.

desert quiver
#

I was fine with bump, but extend or extend_ttl is fine (the latter if we do a good scrape and ensure we use ttl consistently, as things like get_max_entry_ttl help).

Mostly happy the args names are switching to extend_ttl(key, threshold, extend_to).

hidden palm
#

i guess the extend_to is more intuitive proided that extend_ttl becomes a thing. when it was called bump i would have said extend_by was better... but by adding the ttl naming, it makes extend_to make more sense and more intuitive

desert quiver
hidden palm
#

It is a stretch, yes, but even me with my background of being a network engineer long before i was a software dev, and TTL meaning what it should mean here, my brain first was still thinking time til live instead of time to live. I think it's because of livebeing a heteronym

#

but overall i still think it's better than what exists now.

hidden palm
gritty stone
#

there should be get_max_expiration_ledger in the env. I'm not sure if/how we expose it via sdk...

hidden palm
#

i'll check one min

#

I'm not seeing it in either when i search that string

#

i searched expiration also and went through a bunch of stuff and must be overlooking it. maybe the name has already been changed?

gritty stone
#

no, it just would mean that we don't expose it in that release yet... (since plumbing is manual it's easy to forget to add SDK getter)

#

you can patch SDK to expose this, or wait for the next release

hidden palm
#

I will but i can't find it in the host

gritty stone
#

(patch would be just add a getter e.g. into ledger.rs in the same way as we have other ledger info getters)

hidden palm
#

let me check

#

i was lookin gin storage thanks

gritty stone
#

hmm, sure, it's not there at head

hidden palm
#

i found it

#

max_live_until_ledger

gritty stone
#

yes, if you use head

hidden palm
#
  /// Returns the maximum ledger sequence number that data can live to.
    #[doc(hidden)]
    pub fn max_live_until_ledger(&self) -> u32 {
        internal::Env::get_max_live_until_ledger(self.env())
            .unwrap_infallible()
            .into()
    }
gritty stone
#

(you probably don't want to though)

hidden palm
#

yeah that first line expiration_ledger is a arg

#

if that's what you were talking about

gritty stone
#

that's the implementation, yes

hidden palm
#

thanks

#

so yeah it is here i just had the name wrong

gritty stone
#

it's just that you'd need to use head revision of env and SDK, and doing so would result in generating wasm incompatible with future/testnet

hidden palm
#

True so yeah i see what you're saying

#

if it's not in the env in the release version either then well

gritty stone
#

so if you want this for rc2 SDK, you'd need to do the patch and use the old name

hidden palm
#

I guess i'll just have to wait, i was mostely just wanting to answer alex's question

gritty stone
#

it should be in env in the current release version

hidden palm
#

rc1 is current right?

gritty stone
#

hmm, is it not rc2?

hidden palm
#

i don't know that's why i'm asking lol one sec

#

no okay it is rc2

#

and ini rc2 it is the other name

#

I think i can wait til the new sdk and env are released