Skip to content

Commit 36f4e06

Browse files
feat: add utils function to map postage batch (#1130)
* feat: add utils function to map postage batch * feat: add unmap function for symmetry * test: update test coverage --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 6481f90 commit 36f4e06

5 files changed

Lines changed: 96 additions & 85 deletions

File tree

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { BeeDev } from './bee-dev'
33
import { Stamper } from './stamper/stamper'
44

55
export { MerkleTree } from 'cafe-utility'
6-
export { Chunk } from './chunk/cac'
7-
export { SingleOwnerChunk } from './chunk/soc'
6+
export type { Chunk } from './chunk/cac'
7+
export type { SingleOwnerChunk } from './chunk/soc'
88
export { MantarayNode } from './manifest/manifest'
99
export { SUPPORTED_BEE_VERSION, SUPPORTED_BEE_VERSION_EXACT } from './modules/debug/status'
1010
export * from './types'

src/modules/debug/stamps.ts

Lines changed: 18 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@ import type {
88
PostageBatchOptions,
99
RedundancyLevel,
1010
} from '../../types'
11-
import { Duration } from '../../utils/duration'
1211
import { http } from '../../utils/http'
13-
import { Size } from '../../utils/size'
14-
import { getStampEffectiveBytes, getStampTheoreticalBytes, getStampUsage } from '../../utils/stamps'
12+
import { mapPostageBatch, RawPostageBatch } from '../../utils/stamps'
1513
import { asNumberString } from '../../utils/type'
1614
import { BatchId, EthAddress } from '../../utils/typed-bytes'
17-
import { normalizeBatchTTL } from '../../utils/workaround'
1815

1916
const STAMPS_ENDPOINT = 'stamps'
2017
const BATCHES_ENDPOINT = 'batches'
@@ -51,44 +48,7 @@ export async function getAllPostageBatches(requestOptions: BeeRequestOptions): P
5148
const body = Types.asObject(response.data, { name: 'response.data' })
5249
const stamps = Types.asArray(body.stamps, { name: 'stamps' }).map(x => Types.asObject(x, { name: 'stamp' }))
5350

54-
return stamps.map(x => {
55-
const utilization = Types.asNumber(x.utilization, { name: 'utilization' })
56-
const depth = Types.asNumber(x.depth, { name: 'depth' })
57-
const bucketDepth = Types.asNumber(x.bucketDepth, { name: 'bucketDepth' })
58-
const usage = getStampUsage(utilization, depth, bucketDepth)
59-
const batchTTL = normalizeBatchTTL(Types.asNumber(x.batchTTL, { name: 'batchTTL' }))
60-
const duration = Duration.fromSeconds(batchTTL)
61-
62-
const effectiveBytes = getStampEffectiveBytes(depth)
63-
64-
return {
65-
batchID: new BatchId(Types.asString(x.batchID, { name: 'batchID' })),
66-
utilization,
67-
usable: Types.asBoolean(x.usable, { name: 'usable' }),
68-
label: Types.asEmptiableString(x.label, { name: 'label' }),
69-
depth,
70-
amount: asNumberString(x.amount, { name: 'amount' }),
71-
bucketDepth,
72-
blockNumber: Types.asNumber(x.blockNumber, { name: 'blockNumber' }),
73-
immutableFlag: Types.asBoolean(x.immutableFlag, { name: 'immutableFlag' }),
74-
usage,
75-
usageText: `${Math.round(usage * 100)}%`,
76-
size: Size.fromBytes(effectiveBytes),
77-
remainingSize: Size.fromBytes(Math.ceil(effectiveBytes * (1 - usage))),
78-
theoreticalSize: Size.fromBytes(getStampTheoreticalBytes(depth)),
79-
duration,
80-
calculateSize(encryption, redundancyLevel) {
81-
const effectiveBytes = getStampEffectiveBytes(this.depth, encryption, redundancyLevel)
82-
83-
return Size.fromBytes(effectiveBytes)
84-
},
85-
calculateRemainingSize(encryption, redundancyLevel) {
86-
const effectiveBytes = getStampEffectiveBytes(this.depth, encryption, redundancyLevel)
87-
88-
return Size.fromBytes(Math.ceil(effectiveBytes * (1 - this.usage)))
89-
},
90-
}
91-
})
51+
return stamps.map(x => mapPostageBatch(validateRawPostageBatch(x)))
9252
}
9353

9454
export async function getPostageBatch(
@@ -105,42 +65,7 @@ export async function getPostageBatch(
10565

10666
const body = Types.asObject(response.data, { name: 'response.data' })
10767

108-
const utilization = Types.asNumber(body.utilization, { name: 'utilization' })
109-
const depth = Types.asNumber(body.depth, { name: 'depth' })
110-
const bucketDepth = Types.asNumber(body.bucketDepth, { name: 'bucketDepth' })
111-
const usage = getStampUsage(utilization, depth, bucketDepth)
112-
const batchTTL = normalizeBatchTTL(Types.asNumber(body.batchTTL, { name: 'batchTTL' }))
113-
const duration = Duration.fromSeconds(batchTTL)
114-
115-
const effectiveBytes = getStampEffectiveBytes(depth, encryption, erasureCodeLevel)
116-
117-
return {
118-
batchID: new BatchId(Types.asString(body.batchID, { name: 'batchID' })),
119-
utilization,
120-
usable: Types.asBoolean(body.usable, { name: 'usable' }),
121-
label: Types.asEmptiableString(body.label, { name: 'label' }),
122-
depth,
123-
amount: asNumberString(body.amount, { name: 'amount' }),
124-
bucketDepth,
125-
blockNumber: Types.asNumber(body.blockNumber, { name: 'blockNumber' }),
126-
immutableFlag: Types.asBoolean(body.immutableFlag, { name: 'immutableFlag' }),
127-
usage,
128-
usageText: `${Math.round(usage * 100)}%`,
129-
size: Size.fromBytes(effectiveBytes),
130-
remainingSize: Size.fromBytes(Math.ceil(effectiveBytes * (1 - usage))),
131-
theoreticalSize: Size.fromBytes(getStampTheoreticalBytes(depth)),
132-
duration,
133-
calculateSize(encryption, redundancyLevel) {
134-
const effectiveBytes = getStampEffectiveBytes(depth, encryption, redundancyLevel)
135-
136-
return Size.fromBytes(effectiveBytes)
137-
},
138-
calculateRemainingSize(encryption, redundancyLevel) {
139-
const effectiveBytes = getStampEffectiveBytes(depth, encryption, redundancyLevel)
140-
141-
return Size.fromBytes(Math.ceil(effectiveBytes * (1 - usage)))
142-
},
143-
}
68+
return mapPostageBatch(validateRawPostageBatch(body), encryption, erasureCodeLevel)
14469
}
14570

14671
export async function getPostageBatchBuckets(
@@ -224,3 +149,18 @@ export async function diluteBatch(requestOptions: BeeRequestOptions, id: BatchId
224149

225150
return new BatchId(Types.asString(body.batchID, { name: 'batchID' }))
226151
}
152+
153+
function validateRawPostageBatch(raw: Record<string, unknown>): RawPostageBatch {
154+
return {
155+
amount: asNumberString(raw.amount, { name: 'amount' }),
156+
batchID: Types.asString(raw.batchID, { name: 'batchID' }),
157+
batchTTL: Types.asNumber(raw.batchTTL, { name: 'batchTTL' }),
158+
bucketDepth: Types.asNumber(raw.bucketDepth, { name: 'bucketDepth' }),
159+
blockNumber: Types.asNumber(raw.blockNumber, { name: 'blockNumber' }),
160+
depth: Types.asNumber(raw.depth, { name: 'depth' }),
161+
immutableFlag: Types.asBoolean(raw.immutableFlag, { name: 'immutableFlag' }),
162+
label: Types.asEmptiableString(raw.label, { name: 'label' }),
163+
usable: Types.asBoolean(raw.usable, { name: 'usable' }),
164+
utilization: Types.asNumber(raw.utilization, { name: 'utilization' }),
165+
}
166+
}

src/utils/expose.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ export {
1111
getStampEffectiveBytesBreakpoints,
1212
getStampTheoreticalBytes,
1313
getStampUsage,
14+
mapPostageBatch,
15+
unmapPostageBatch,
1416
} from './stamps'

src/utils/stamps.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { Binary } from 'cafe-utility'
2-
import { capacityBreakpoints, EnvelopeWithBatchId, NumberString, RedundancyLevel } from '../types'
2+
import { capacityBreakpoints, EnvelopeWithBatchId, NumberString, PostageBatch, RedundancyLevel } from '../types'
33
import { Bytes, parseSizeToBytes } from './bytes'
44
import { Duration } from './duration'
55
import { Size } from './size'
66
import { BZZ } from './tokens'
77
import { asNumberString } from './type'
8+
import { BatchId } from './typed-bytes'
9+
import { normalizeBatchTTL } from './workaround'
810

911
const MAX_UTILIZATION = 0.9
1012

@@ -200,3 +202,70 @@ export function marshalStamp(
200202

201203
return new Bytes(Binary.concatBytes(batchId, index, timestamp, signature))
202204
}
205+
206+
export interface RawPostageBatch {
207+
batchID: string
208+
utilization: number
209+
usable: boolean
210+
label: string
211+
depth: number
212+
amount: string
213+
bucketDepth: number
214+
blockNumber: number
215+
immutableFlag: boolean
216+
batchTTL: number
217+
}
218+
219+
export function mapPostageBatch(
220+
raw: RawPostageBatch,
221+
encryption?: boolean,
222+
erasureCodeLevel?: RedundancyLevel,
223+
): PostageBatch {
224+
const usage = getStampUsage(raw.utilization, raw.depth, raw.bucketDepth)
225+
const batchTTL = normalizeBatchTTL(raw.batchTTL)
226+
const duration = Duration.fromSeconds(batchTTL)
227+
const effectiveBytes = getStampEffectiveBytes(raw.depth, encryption, erasureCodeLevel)
228+
229+
return {
230+
batchID: new BatchId(raw.batchID),
231+
utilization: raw.utilization,
232+
usable: raw.usable,
233+
label: raw.label,
234+
depth: raw.depth,
235+
amount: asNumberString(raw.amount),
236+
bucketDepth: raw.bucketDepth,
237+
blockNumber: raw.blockNumber,
238+
immutableFlag: raw.immutableFlag,
239+
usage,
240+
usageText: `${Math.round(usage * 100)}%`,
241+
size: Size.fromBytes(effectiveBytes),
242+
remainingSize: Size.fromBytes(Math.ceil(effectiveBytes * (1 - usage))),
243+
theoreticalSize: Size.fromBytes(getStampTheoreticalBytes(raw.depth)),
244+
duration,
245+
calculateSize(encryption, redundancyLevel) {
246+
const effectiveBytes = getStampEffectiveBytes(raw.depth, encryption, redundancyLevel)
247+
248+
return Size.fromBytes(effectiveBytes)
249+
},
250+
calculateRemainingSize(encryption, redundancyLevel) {
251+
const effectiveBytes = getStampEffectiveBytes(raw.depth, encryption, redundancyLevel)
252+
253+
return Size.fromBytes(Math.ceil(effectiveBytes * (1 - this.usage)))
254+
},
255+
}
256+
}
257+
258+
export function unmapPostageBatch(batch: PostageBatch): RawPostageBatch {
259+
return {
260+
batchID: batch.batchID.toHex(),
261+
utilization: batch.utilization,
262+
usable: batch.usable,
263+
label: batch.label,
264+
depth: batch.depth,
265+
amount: batch.amount,
266+
bucketDepth: batch.bucketDepth,
267+
blockNumber: batch.blockNumber,
268+
immutableFlag: batch.immutableFlag,
269+
batchTTL: batch.duration.toSeconds(),
270+
}
271+
}

test/coverage/coverage-summary.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{"total": {"lines":{"total":2494,"covered":2045,"skipped":0,"pct":81.99},"statements":{"total":2538,"covered":2085,"skipped":0,"pct":82.15},"functions":{"total":608,"covered":484,"skipped":0,"pct":79.6},"branches":{"total":578,"covered":374,"skipped":0,"pct":64.7},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
1+
{"total": {"lines":{"total":2486,"covered":2040,"skipped":0,"pct":82.05},"statements":{"total":2531,"covered":2081,"skipped":0,"pct":82.22},"functions":{"total":611,"covered":486,"skipped":0,"pct":79.54},"branches":{"total":578,"covered":374,"skipped":0,"pct":64.7},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
22
,"/home/runner/work/bee-js/bee-js/src/bee-dev.ts": {"lines":{"total":14,"covered":5,"skipped":0,"pct":35.71},"functions":{"total":2,"covered":0,"skipped":0,"pct":0},"statements":{"total":14,"covered":5,"skipped":0,"pct":35.71},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
33
,"/home/runner/work/bee-js/bee-js/src/bee.ts": {"lines":{"total":453,"covered":377,"skipped":0,"pct":83.22},"functions":{"total":132,"covered":108,"skipped":0,"pct":81.81},"statements":{"total":456,"covered":380,"skipped":0,"pct":83.33},"branches":{"total":123,"covered":75,"skipped":0,"pct":60.97}}
44
,"/home/runner/work/bee-js/bee-js/src/index.ts": {"lines":{"total":16,"covered":16,"skipped":0,"pct":100},"functions":{"total":10,"covered":7,"skipped":0,"pct":70},"statements":{"total":25,"covered":25,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
@@ -28,7 +28,7 @@
2828
,"/home/runner/work/bee-js/bee-js/src/modules/debug/connectivity.ts": {"lines":{"total":35,"covered":28,"skipped":0,"pct":80},"functions":{"total":11,"covered":7,"skipped":0,"pct":63.63},"statements":{"total":36,"covered":29,"skipped":0,"pct":80.55},"branches":{"total":2,"covered":2,"skipped":0,"pct":100}}
2929
,"/home/runner/work/bee-js/bee-js/src/modules/debug/settlements.ts": {"lines":{"total":18,"covered":18,"skipped":0,"pct":100},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":18,"covered":18,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
3030
,"/home/runner/work/bee-js/bee-js/src/modules/debug/stake.ts": {"lines":{"total":32,"covered":21,"skipped":0,"pct":65.62},"functions":{"total":6,"covered":3,"skipped":0,"pct":50},"statements":{"total":32,"covered":21,"skipped":0,"pct":65.62},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
31-
,"/home/runner/work/bee-js/bee-js/src/modules/debug/stamps.ts": {"lines":{"total":70,"covered":60,"skipped":0,"pct":85.71},"functions":{"total":17,"covered":13,"skipped":0,"pct":76.47},"statements":{"total":73,"covered":63,"skipped":0,"pct":86.3},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}
31+
,"/home/runner/work/bee-js/bee-js/src/modules/debug/stamps.ts": {"lines":{"total":45,"covered":43,"skipped":0,"pct":95.55},"functions":{"total":14,"covered":14,"skipped":0,"pct":100},"statements":{"total":49,"covered":47,"skipped":0,"pct":95.91},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}
3232
,"/home/runner/work/bee-js/bee-js/src/modules/debug/states.ts": {"lines":{"total":29,"covered":24,"skipped":0,"pct":82.75},"functions":{"total":5,"covered":4,"skipped":0,"pct":80},"statements":{"total":29,"covered":24,"skipped":0,"pct":82.75},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
3333
,"/home/runner/work/bee-js/bee-js/src/modules/debug/status.ts": {"lines":{"total":36,"covered":34,"skipped":0,"pct":94.44},"functions":{"total":7,"covered":6,"skipped":0,"pct":85.71},"statements":{"total":36,"covered":34,"skipped":0,"pct":94.44},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
3434
,"/home/runner/work/bee-js/bee-js/src/modules/debug/transactions.ts": {"lines":{"total":27,"covered":18,"skipped":0,"pct":66.66},"functions":{"total":5,"covered":3,"skipped":0,"pct":60},"statements":{"total":27,"covered":18,"skipped":0,"pct":66.66},"branches":{"total":1,"covered":0,"skipped":0,"pct":0}}
@@ -48,7 +48,7 @@
4848
,"/home/runner/work/bee-js/bee-js/src/utils/data.ts": {"lines":{"total":11,"covered":4,"skipped":0,"pct":36.36},"functions":{"total":3,"covered":1,"skipped":0,"pct":33.33},"statements":{"total":12,"covered":4,"skipped":0,"pct":33.33},"branches":{"total":7,"covered":1,"skipped":0,"pct":14.28}}
4949
,"/home/runner/work/bee-js/bee-js/src/utils/duration.ts": {"lines":{"total":22,"covered":20,"skipped":0,"pct":90.9},"functions":{"total":17,"covered":15,"skipped":0,"pct":88.23},"statements":{"total":22,"covered":20,"skipped":0,"pct":90.9},"branches":{"total":5,"covered":5,"skipped":0,"pct":100}}
5050
,"/home/runner/work/bee-js/bee-js/src/utils/error.ts": {"lines":{"total":12,"covered":12,"skipped":0,"pct":100},"functions":{"total":3,"covered":3,"skipped":0,"pct":100},"statements":{"total":12,"covered":12,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
51-
,"/home/runner/work/bee-js/bee-js/src/utils/expose.ts": {"lines":{"total":13,"covered":13,"skipped":0,"pct":100},"functions":{"total":15,"covered":14,"skipped":0,"pct":93.33},"statements":{"total":20,"covered":20,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
51+
,"/home/runner/work/bee-js/bee-js/src/utils/expose.ts": {"lines":{"total":15,"covered":15,"skipped":0,"pct":100},"functions":{"total":17,"covered":14,"skipped":0,"pct":82.35},"statements":{"total":22,"covered":22,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
5252
,"/home/runner/work/bee-js/bee-js/src/utils/file.ts": {"lines":{"total":12,"covered":8,"skipped":0,"pct":66.66},"functions":{"total":4,"covered":2,"skipped":0,"pct":50},"statements":{"total":13,"covered":8,"skipped":0,"pct":61.53},"branches":{"total":8,"covered":6,"skipped":0,"pct":75}}
5353
,"/home/runner/work/bee-js/bee-js/src/utils/headers.ts": {"lines":{"total":71,"covered":62,"skipped":0,"pct":87.32},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":71,"covered":62,"skipped":0,"pct":87.32},"branches":{"total":39,"covered":31,"skipped":0,"pct":79.48}}
5454
,"/home/runner/work/bee-js/bee-js/src/utils/http.ts": {"lines":{"total":37,"covered":32,"skipped":0,"pct":86.48},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":37,"covered":32,"skipped":0,"pct":86.48},"branches":{"total":23,"covered":15,"skipped":0,"pct":65.21}}
@@ -57,7 +57,7 @@
5757
,"/home/runner/work/bee-js/bee-js/src/utils/redundancy.ts": {"lines":{"total":44,"covered":32,"skipped":0,"pct":72.72},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":45,"covered":33,"skipped":0,"pct":73.33},"branches":{"total":26,"covered":12,"skipped":0,"pct":46.15}}
5858
,"/home/runner/work/bee-js/bee-js/src/utils/resource-locator.ts": {"lines":{"total":7,"covered":7,"skipped":0,"pct":100},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":7,"covered":7,"skipped":0,"pct":100},"branches":{"total":3,"covered":3,"skipped":0,"pct":100}}
5959
,"/home/runner/work/bee-js/bee-js/src/utils/size.ts": {"lines":{"total":14,"covered":12,"skipped":0,"pct":85.71},"functions":{"total":10,"covered":9,"skipped":0,"pct":90},"statements":{"total":14,"covered":12,"skipped":0,"pct":85.71},"branches":{"total":1,"covered":0,"skipped":0,"pct":0}}
60-
,"/home/runner/work/bee-js/bee-js/src/utils/stamps.ts": {"lines":{"total":63,"covered":45,"skipped":0,"pct":71.42},"functions":{"total":13,"covered":11,"skipped":0,"pct":84.61},"statements":{"total":65,"covered":46,"skipped":0,"pct":70.76},"branches":{"total":22,"covered":8,"skipped":0,"pct":36.36}}
60+
,"/home/runner/work/bee-js/bee-js/src/utils/stamps.ts": {"lines":{"total":78,"covered":55,"skipped":0,"pct":70.51},"functions":{"total":17,"covered":12,"skipped":0,"pct":70.58},"statements":{"total":80,"covered":56,"skipped":0,"pct":70},"branches":{"total":22,"covered":8,"skipped":0,"pct":36.36}}
6161
,"/home/runner/work/bee-js/bee-js/src/utils/tar-uploader.browser.ts": {"lines":{"total":11,"covered":0,"skipped":0,"pct":0},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":11,"covered":0,"skipped":0,"pct":0},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
6262
,"/home/runner/work/bee-js/bee-js/src/utils/tar-uploader.ts": {"lines":{"total":12,"covered":12,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":12,"covered":12,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
6363
,"/home/runner/work/bee-js/bee-js/src/utils/tar-writer.browser.ts": {"lines":{"total":8,"covered":0,"skipped":0,"pct":0},"functions":{"total":1,"covered":0,"skipped":0,"pct":0},"statements":{"total":8,"covered":0,"skipped":0,"pct":0},"branches":{"total":2,"covered":0,"skipped":0,"pct":0}}

0 commit comments

Comments
 (0)