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 @@

const log = logger('ipns')
const ID_MULTIHASH_CODE = identity.code
const DEFAULT_TTL_NS = 60 * 60 * 1e+9 // 1 Hour or 3600 Seconds

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

export interface CreateOptions {
ttlNs?: number | bigint
v1Compatible?: boolean
}

Expand All @@ -140,7 +142,8 @@
}

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

/**
Expand All @@ -167,10 +170,9 @@
// 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)

Check failure on line 175 in src/index.ts

View workflow job for this annotation

GitHub Actions / js-test-and-release / check

Argument of type 'number | bigint' is not assignable to parameter of type 'bigint'.
}

/**
Expand All @@ -195,11 +197,9 @@
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)

Check failure on line 202 in src/index.ts

View workflow job for this annotation

GitHub Actions / js-test-and-release / check

Argument of type 'number | bigint' is not assignable to parameter of type 'bigint'.
}

const _create = async (peerId: PeerId, value: CID | PeerId | string, seq: number | bigint, validityType: IpnsEntry.ValidityType, validity: string, ttl: bigint, options: CreateOptions = defaultCreateOptions): Promise<IPNSRecord> => {
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 = 3.6e+12
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 = 3.6e+12
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 = 0.6e+12
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(marshalledRecord)
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