@ethersphere/bee-js
Version:
Javascript client for Bee
152 lines (151 loc) • 5.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.marshalStamp = exports.convertEnvelopeToMarshaledStamp = exports.getDepthForSize = exports.getAmountForDuration = exports.getStampDuration = exports.getStampCost = exports.getStampEffectiveBytesBreakpoints = exports.getStampEffectiveBytes = exports.getStampTheoreticalBytes = exports.getStampUsage = void 0;
const cafe_utility_1 = require("cafe-utility");
const bytes_1 = require("./bytes");
const duration_1 = require("./duration");
const tokens_1 = require("./tokens");
const type_1 = require("./type");
const MAX_UTILIZATION = 0.9;
/**
* Utility function that calculates usage of postage batch based on its utilization, depth and bucket depth.
*
* For smaller depths (up to 20), this may provide less accurate results.
*
* @returns {number} A number between 0 and 1 representing the usage of the postage batch.
*/
function getStampUsage(utilization, depth, bucketDepth) {
return utilization / Math.pow(2, depth - bucketDepth);
}
exports.getStampUsage = getStampUsage;
/**
* Utility function that calculates the theoritical maximum size of a postage batch based on its depth.
*
* For smaller depths (up to 22), this may provide less accurate results.
*
* @returns {number} The maximum theoretical size of the postage batch in bytes.
*/
function getStampTheoreticalBytes(depth) {
return 4096 * 2 ** depth;
}
exports.getStampTheoreticalBytes = getStampTheoreticalBytes;
/**
* Based on https://docs.ethswarm.org/docs/learn/technology/contracts/postage-stamp/#effective-utilisation-table
* Optimised for encrypted, medium erasure coding
*/
const effectiveSizeBreakpoints = [
[17, 0.00004089],
[18, 0.00609],
[19, 0.10249],
[20, 0.62891],
[21, 2.38],
[22, 7.07],
[23, 18.24],
[24, 43.04],
[25, 96.5],
[26, 208.52],
[27, 435.98],
[28, 908.81],
[29, 1870],
[30, 3810],
[31, 7730],
[32, 15610],
[33, 31430],
[34, 63150],
];
/**
* Utility function that calculates the effective size of a postage batch based on its depth.
*
* Below 22 depth the effective size is 0
* Above 34 it's always > 99%
*
* @returns {number} The effective size of the postage batch in bytes.
*/
function getStampEffectiveBytes(depth) {
if (depth < 17) {
return 0;
}
const breakpoint = effectiveSizeBreakpoints.find(([d, size]) => {
if (depth === d) {
return size;
}
});
if (breakpoint) {
return breakpoint[1] * 1000 * 1000 * 1000;
}
return Math.ceil(getStampTheoreticalBytes(depth) * MAX_UTILIZATION);
}
exports.getStampEffectiveBytes = getStampEffectiveBytes;
function getStampEffectiveBytesBreakpoints() {
const map = new Map();
for (let i = 17; i < 35; i++) {
map.set(i, getStampEffectiveBytes(i));
}
return map;
}
exports.getStampEffectiveBytesBreakpoints = getStampEffectiveBytesBreakpoints;
/**
* Utility function that calculates the cost of a postage batch based on its depth and amount.
*/
function getStampCost(depth, amount) {
return tokens_1.BZZ.fromPLUR(2n ** BigInt(depth) * BigInt(amount));
}
exports.getStampCost = getStampCost;
/**
* Utility function that calculates the TTL of a postage batch based on its amount, price per block and block time.
*
* For more accurate results, get the price per block and block time from the Bee node or the blockchain.
*
* @returns {number} The TTL of the postage batch.
*/
function getStampDuration(amount, pricePerBlock, blockTime) {
const amountBigInt = BigInt((0, type_1.asNumberString)(amount));
return duration_1.Duration.fromSeconds(Number((amountBigInt * BigInt(blockTime)) / BigInt(pricePerBlock)));
}
exports.getStampDuration = getStampDuration;
/**
* Get the postage batch `amount` required for a given `duration`.
*
* @param duration A duration object representing the duration of the storage.
* @param pricePerBlock The price per block in PLUR.
* @param blockTime The block time in seconds.
*/
function getAmountForDuration(duration, pricePerBlock, blockTime) {
return (BigInt(duration.toSeconds()) / BigInt(blockTime)) * BigInt(pricePerBlock) + 1n;
}
exports.getAmountForDuration = getAmountForDuration;
/**
* Utility function that calculates the depth required for a postage batch to achieve the specified effective size
*
* @param size The effective size of the postage batch
* @returns
*/
function getDepthForSize(size) {
for (const [depth, sizeBreakpoint] of effectiveSizeBreakpoints) {
if (size.toBytes() <= sizeBreakpoint * 1000 * 1000 * 1000) {
return depth;
}
}
return 35;
}
exports.getDepthForSize = getDepthForSize;
function convertEnvelopeToMarshaledStamp(envelope) {
return marshalStamp(envelope.signature, envelope.batchId.toUint8Array(), envelope.timestamp, envelope.index);
}
exports.convertEnvelopeToMarshaledStamp = convertEnvelopeToMarshaledStamp;
function marshalStamp(signature, batchId, timestamp, index) {
if (signature.length !== 65) {
throw Error('invalid signature length');
}
if (batchId.length !== 32) {
throw Error('invalid batch ID length');
}
if (timestamp.length !== 8) {
throw Error('invalid timestamp length');
}
if (index.length !== 8) {
throw Error('invalid index length');
}
return new bytes_1.Bytes(cafe_utility_1.Binary.concatBytes(batchId, index, timestamp, signature));
}
exports.marshalStamp = marshalStamp;