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: support for waiting on stamp to be usable #678

Merged
merged 1 commit into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions src/bee-debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ import type {
NodeInfo,
BeeVersions,
} from './types'
import { BeeArgumentError } from './utils/error'
import { BeeArgumentError, BeeError } from './utils/error'
import { assertBeeUrl, stripLastSlash } from './utils/url'
import {
assertAddress,
assertBatchId,
assertBoolean,
assertCashoutOptions,
assertNonNegativeInteger,
assertPostageBatchOptions,
assertRequestOptions,
assertTransactionHash,
isTag,
Expand All @@ -60,6 +60,7 @@ import * as tag from './modules/debug/tag'
import * as stamps from './modules/debug/stamps'
import type { Options as KyOptions } from 'ky-universal'
import { makeDefaultKy, wrapRequestClosure, wrapResponseClosure } from './utils/http'
import { sleep } from '../test/utils'

export class BeeDebug {
/**
Expand Down Expand Up @@ -499,7 +500,7 @@ export class BeeDebug {
* @see [Bee Debug API reference - `POST /stamps`](https://docs.ethswarm.org/debug-api/#tag/Postage-Stamps/paths/~1stamps~1{amount}~1{depth}/post)
*/
async createPostageBatch(amount: NumberString, depth: number, options?: PostageBatchOptions): Promise<BatchId> {
assertRequestOptions(options)
assertPostageBatchOptions(options)
assertNonNegativeInteger(amount)
assertNonNegativeInteger(depth)

Expand All @@ -511,15 +512,13 @@ export class BeeDebug {
throw new BeeArgumentError(`Depth has to be at most ${STAMPS_DEPTH_MAX}`, depth)
}

if (options?.gasPrice) {
assertNonNegativeInteger(options.gasPrice)
}
const stamp = await stamps.createPostageBatch(this.getKy(options), amount, depth, options)

if (options?.immutableFlag !== undefined) {
assertBoolean(options.immutableFlag)
AuHau marked this conversation as resolved.
Show resolved Hide resolved
if (options?.waitForUsable) {
await this.waitForUsablePostageStamp(stamp, options?.waitForUsableTimeout)
}

return stamps.createPostageBatch(this.getKy(options), amount, depth, options)
return stamp
}

/**
Expand Down Expand Up @@ -673,6 +672,21 @@ export class BeeDebug {
return transactions.cancelTransaction(this.getKy(options), transactionHash, gasPrice)
}

private async waitForUsablePostageStamp(id: BatchId, timeout = 120_000): Promise<void> {
const TIME_STEP = 1500
for (let time = 0; time < timeout; time += TIME_STEP) {
const stamp = await this.getPostageBatch(id)

if (stamp.usable) {
return
}

await sleep(TIME_STEP)
}

throw new BeeError('Timeout on waiting for postage stamp to become usable')
}

private getKy(options?: RequestOptions): Ky {
if (!options) {
return this.ky
Expand Down
18 changes: 18 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,24 @@ export interface PostageBatchOptions extends RequestOptions {
*/
gasPrice?: NumberString
immutableFlag?: boolean

/**
* The returned Promise will await until the purchased Postage Batch is usable.
* In other word, it has to have enough block confirmations that Bee pronounce it usable.
* If turned on, this significantly prolong the creation of postage batch!
* If you plan to use the stamp right away for some action with Bee (like uploading using this stamp) it is
* highly recommended to use this option, otherwise you might get errors "stamp not usable" from Bee.
*
* In next breaking release this option will be turned on by default.
* @default false
*/
waitForUsable?: boolean

/**
* When waiting for the postage stamp to become usable, this specify the timeout for the waiting.
* Default: 120s
*/
waitForUsableTimeout?: number
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/utils/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,14 @@ export function assertPostageBatchOptions(value: unknown): asserts value is Post
if (options?.immutableFlag !== undefined) {
assertBoolean(options.immutableFlag)
}

if (options?.waitForUsable !== undefined) {
assertBoolean(options.waitForUsable)
}

if (options?.waitForUsableTimeout !== undefined) {
assertNonNegativeInteger(options.waitForUsableTimeout, 'options.waitForUsableTimeout')
}
}

export function assertCashoutOptions(value: unknown): asserts value is CashoutOptions {
Expand Down
25 changes: 22 additions & 3 deletions test/integration/bee-debug-class.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { BeeArgumentError, BeeDebug } from '../../src'
import { beeDebugUrl, commonMatchers, getOrCreatePostageBatch, BLOCKCHAIN_TRANSACTION_TIMEOUT, sleep } from '../utils'
import {
beeDebugUrl,
commonMatchers,
getOrCreatePostageBatch,
BLOCKCHAIN_TRANSACTION_TIMEOUT,
sleep,
WAITING_USABLE_STAMP_TIMEOUT,
} from '../utils'

commonMatchers()

Expand All @@ -9,16 +16,28 @@ describe('Bee Debug class', () => {

describe('PostageBatch', () => {
it(
'should create a new postage batch with zero amount',
'should create a new postage batch with zero amount and be un-usable',
async () => {
const batchId = await beeDebug.createPostageBatch('0', 17)
const allBatches = await beeDebug.getAllPostageBatch()
const stamp = await beeDebug.getPostageBatch(batchId)
expect(stamp.usable).toEqual(false)

const allBatches = await beeDebug.getAllPostageBatch()
expect(allBatches.find(batch => batch.batchID === batchId)).toBeTruthy()
},
BLOCKCHAIN_TRANSACTION_TIMEOUT,
)

it(
'should wait for the stamp to be usable',
async () => {
const batchId = await beeDebug.createPostageBatch('1000', 17, { waitForUsable: true })
const stamp = await beeDebug.getPostageBatch(batchId)
expect(stamp.usable).toEqual(true)
},
WAITING_USABLE_STAMP_TIMEOUT + BLOCKCHAIN_TRANSACTION_TIMEOUT,
)

// TODO: Finish topup and dilute testing https://github.com/ethersphere/bee-js/issues/427
it.skip(
'should topup postage batch',
Expand Down
1 change: 1 addition & 0 deletions test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ export const BIG_FILE_TIMEOUT = 100_000
export const PSS_TIMEOUT = 120_000
export const FEED_TIMEOUT = 120_000
export const BLOCKCHAIN_TRANSACTION_TIMEOUT = 40_000
export const WAITING_USABLE_STAMP_TIMEOUT = 130_000

export const testChunkPayload = new Uint8Array([1, 2, 3])
// span is the payload length encoded as uint64 little endian
Expand Down