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

feat: change default TTL and add support for custom TTL (#1) #308

Merged
merged 10 commits into from
Apr 2, 2024
14 changes: 7 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { CID } from 'multiformats/cid'

const log = logger('ipns')
const ID_MULTIHASH_CODE = identity.code
const DEFAULT_TTL_NS = BigInt(3.6e+12) // 1 Hour or 3600 Seconds
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved

export const namespace = '/ipns/'
export const namespaceLength = namespace.length
Expand Down Expand Up @@ -128,6 +129,7 @@ export interface IDKeys {
}

export interface CreateOptions {
ttlNs?: bigint
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved
v1Compatible?: boolean
}

Expand All @@ -140,7 +142,8 @@ export interface CreateV2Options {
}

const defaultCreateOptions: CreateOptions = {
v1Compatible: true
v1Compatible: true,
ttlNs: DEFAULT_TTL_NS
}

/**
Expand All @@ -167,10 +170,9 @@ export async function create (peerId: PeerId, value: CID | PeerId | string, seq:
// Validity in ISOString with nanoseconds precision and validity type EOL
const expirationDate = new NanoDate(Date.now() + Number(lifetime))
const validityType = IpnsEntry.ValidityType.EOL
const [ms, ns] = lifetime.toString().split('.')
const lifetimeNs = (BigInt(ms) * BigInt(100000)) + BigInt(ns ?? '0')
const ttlNs = typeof options.ttlNs !== 'undefined' ? BigInt(options.ttlNs) : DEFAULT_TTL_NS
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved

return _create(peerId, value, seq, validityType, expirationDate.toString(), lifetimeNs, options)
return _create(peerId, value, seq, validityType, expirationDate.toString(), ttlNs, options)
}

/**
Expand All @@ -195,9 +197,7 @@ export async function createWithExpiration (peerId: PeerId, value: CID | PeerId
export async function createWithExpiration (peerId: PeerId, value: CID | PeerId | string, seq: number | bigint, expiration: string, options: CreateOptions = defaultCreateOptions): Promise<IPNSRecord> {
const expirationDate = NanoDate.fromString(expiration)
const validityType = IpnsEntry.ValidityType.EOL

const ttlMs = expirationDate.toDate().getTime() - Date.now()
const ttlNs = (BigInt(ttlMs) * BigInt(100000)) + BigInt(expirationDate.getNano())
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved
const ttlNs = typeof options.ttlNs !== 'undefined' ? BigInt(options.ttlNs) : DEFAULT_TTL_NS
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved

return _create(peerId, value, seq, validityType, expirationDate.toString(), ttlNs, options)
}
Expand Down
47 changes: 43 additions & 4 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('ipns', function () {

it('should create an ipns record (V1+V2) correctly', async () => {
const sequence = 0
const ttl = BigInt(3.6e+12)
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved
const validity = 1000000

const record = await ipns.create(peerId, contentPath, sequence, validity)
Expand All @@ -40,7 +41,7 @@ describe('ipns', function () {
expect(record.validityType).to.equal(IpnsEntry.ValidityType.EOL)
expect(record.validity).to.exist()
expect(record.sequence).to.equal(BigInt(0))
expect(record.ttl).to.equal(BigInt(validity * 100000))
expect(record.ttl).to.equal(ttl)
expect(record.signatureV1).to.exist()
expect(record.signatureV2).to.exist()
expect(record.data).to.exist()
Expand All @@ -51,7 +52,7 @@ describe('ipns', function () {
expect(pb.validityType).to.equal(IpnsEntry.ValidityType.EOL)
expect(pb.validity).to.exist()
expect(pb.sequence).to.equal(BigInt(sequence))
expect(pb.ttl).to.equal(BigInt(validity * 100000))
expect(pb.ttl).to.equal(ttl)
expect(pb.signatureV1).to.exist()
expect(pb.signatureV2).to.exist()
expect(pb.data).to.exist()
Expand All @@ -67,6 +68,7 @@ describe('ipns', function () {

it('should create an ipns record (V2) correctly', async () => {
const sequence = 0
const ttl = BigInt(3.6e+12)
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved
const validity = 1000000

const record = await ipns.create(peerId, contentPath, sequence, validity, { v1Compatible: false })
Expand All @@ -75,7 +77,7 @@ describe('ipns', function () {
expect(record.validityType).to.equal(IpnsEntry.ValidityType.EOL)
expect(record.validity).to.exist()
expect(record.sequence).to.equal(BigInt(0))
expect(record.ttl).to.equal(BigInt(validity * 100000))
expect(record.ttl).to.equal(ttl)
expect(record.signatureV2).to.exist()
expect(record).to.not.have.property('signatureV1')
expect(record.data).to.exist()
Expand All @@ -97,7 +99,7 @@ describe('ipns', function () {
expect(data.ValidityType).to.equal(IpnsEntry.ValidityType.EOL)
expect(data.Validity).to.exist()
expect(data.Sequence).to.equal(BigInt(sequence))
expect(data.TTL).to.equal(BigInt(validity * 100000))
expect(data.TTL).to.equal(ttl)
})

it('should be able to create a record (V1+V2) with a fixed expiration', async () => {
Expand Down Expand Up @@ -130,6 +132,43 @@ describe('ipns', function () {
expect(data.Validity).to.equalBytes(uint8ArrayFromString(expiration))
})

it('should be able to create a record (V1+V2) with a fixed ttl', async () => {
const sequence = 0
const ttl = BigInt(0.6e+12)
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved
const validity = 1000000

const record = await ipns.create(peerId, contentPath, sequence, validity, {
ttlNs: ttl
})
const marshalledRecord = ipns.marshal(record)

await ipnsValidator(peerIdToRoutingKey(peerId), marshalledRecord)

const pb = IpnsEntry.decode(marshalledRecord)
const data = parseCborData(pb.data ?? new Uint8Array(0))
expect(data.TTL).to.equal(ttl)
})

it('should be able to create a record (V2) with a fixed ttl', async () => {
const sequence = 0
const ttl = BigInt(1.6e+12)
const validity = 1000000

const record = await ipns.create(peerId, contentPath, sequence, validity, {
ttlNs: ttl,
v1Compatible: false
})
const marshalledRecord = ipns.marshal(record)

await ipnsValidator(peerIdToRoutingKey(peerId), marshalledRecord)

const pb = IpnsEntry.decode(ipns.marshal(record))
jtsmedley marked this conversation as resolved.
Show resolved Hide resolved
expect(pb).to.not.have.property('ttl')

const data = parseCborData(pb.data ?? new Uint8Array(0))
expect(data.TTL).to.equal(ttl)
})

it('should create an ipns record (V1+V2) and validate it correctly', async () => {
const sequence = 0
const validity = 1000000
Expand Down
Loading