Skip to content

Commit

Permalink
Merge main into release
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] authored Nov 22, 2023
2 parents 4fbc820 + 391ecc4 commit 58b7b98
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ ___

#### Defined in

[src/types/algo-http-client-with-retry.ts:67](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L67)
[src/types/algo-http-client-with-retry.ts:71](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L71)

___

Expand All @@ -170,7 +170,7 @@ ___

#### Defined in

[src/types/algo-http-client-with-retry.ts:54](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L54)
[src/types/algo-http-client-with-retry.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L58)

___

Expand All @@ -197,4 +197,4 @@ ___

#### Defined in

[src/types/algo-http-client-with-retry.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L58)
[src/types/algo-http-client-with-retry.ts:62](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L62)
2 changes: 1 addition & 1 deletion docs/code/modules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ ___
**runWhenIndexerCaughtUp**<`T`\>(`run`): `Promise`<`T`\>

Runs the given indexer call until a 404 error is no longer returned.
Tried every 200ms up to 20 times.
Tried every 200ms up to 100 times.
Very rudimentary implementation designed for automated testing.

#### Type parameters
Expand Down
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const config: Config.InitialOptions = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/*.spec.ts'],
testTimeout: 10000,
setupFiles: ['<rootDir>/tests/setup.ts'],
moduleDirectories: ['node_modules', 'src'],
transform: {
Expand Down
2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ export async function getAppArgsForABICall(args: ABIAppCallArgs, from: SendTrans
: a instanceof Promise
? { txn: (await a).transaction, signer }
: 'transaction' in a
? { txn: a.transaction, signer }
? { txn: a.transaction, signer: 'signer' in a ? getSenderTransactionSigner(a.signer) : signer }
: 'txID' in a
? { txn: a, signer }
: a
Expand Down
48 changes: 48 additions & 0 deletions src/network-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,54 @@ import * as algokit from './'
describe('network-clients', () => {
envResetFixture()

// Don't spam algonode all the time, remove the `skip` to run these manually
describe.skip('Retry', () => {
/*
*https://nodely.io/api/*
The API requests are rate limited per source IP address with request shaping.
A burst of 90 rps is allowed and all responses are delayed artificially to make sure that (if called sequentially) they will not exceed the quota.
Queries exceeding the 90rps in burst or sustained 60rps will get HTTP 429 error.
*/
// Create a mock logger to track the number of retries
const myLogger = {
error: jest.fn(),
warn: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
verbose: jest.fn(),
}
algokit.Config.configure({ logger: myLogger })
afterEach(() => {
jest.clearAllMocks()
})
test('Retries indexer calls', async () => {
const indexer = await algokit.getAlgoIndexerClient(algokit.getAlgoNodeConfig('testnet', 'indexer'))

const response = await Promise.all(
new Array(150).fill(0).map(async (_) => {
return await indexer.lookupAccountByID('XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA').do()
}),
)
expect(response.length).toBe(150)
expect(myLogger.warn).toHaveBeenCalledWith(
'algosdk request failed 1 times. Retrying in 0ms: URLTokenBaseHTTPError: Network request error. Received status 429 (Too Many Requests)',
)
}, 10_000)
test('Retries algod calls', async () => {
const algod = await algokit.getAlgoClient(algokit.getAlgoNodeConfig('testnet', 'algod'))

const response = await Promise.all(
new Array(150).fill(0).map(async (_) => {
return await algod.accountInformation('XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA').do()
}),
)
expect(response.length).toBe(150)
expect(myLogger.warn).toHaveBeenCalledWith(
'algosdk request failed 1 times. Retrying in 0ms: URLTokenBaseHTTPError: Network request error. Received status 429 (Too Many Requests)',
)
}, 10_000)
})

describe('Config', () => {
test('Gets algod config from environment', () => {
process.env.ALGOD_SERVER = 'http://localhost'
Expand Down
4 changes: 2 additions & 2 deletions src/testing/indexer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Runs the given indexer call until a 404 error is no longer returned.
* Tried every 200ms up to 20 times.
* Tried every 200ms up to 100 times.
* Very rudimentary implementation designed for automated testing.
* @example ```typescript
* const transaction = await runWhenIndexerCaughtUp(() => indexer.lookupTransactionByID(txnId).do())
Expand All @@ -20,7 +20,7 @@ export async function runWhenIndexerCaughtUp<T>(run: () => Promise<T>): Promise<
} catch (e: any) {
if (e?.status === 404) {
tries++
if (tries > 20) {
if (tries > 100) {
throw e
}
await new Promise<void>((resolve) => setTimeout(resolve, 200))
Expand Down
6 changes: 5 additions & 1 deletion src/transaction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,14 @@ describe('transaction', () => {
)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
const regex = /RewardsBase:(\d+)/
const match = e.traces[0].message.match(regex)
expect(match).toBeDefined()
const rewardsBase = parseInt(match[1], 10)
expect(e.traces[0].message).toEqual(
`transaction ${txn2.txID()}: overspend (account ${
testAccount.addr
}, data {AccountBaseData:{Status:Offline MicroAlgos:{Raw:9998000} RewardsBase:0 RewardedMicroAlgos:{Raw:0} AuthAddr:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ TotalAppSchema:{_struct:{} NumUint:0 NumByteSlice:0} TotalExtraAppPages:0 TotalAppParams:0 TotalAppLocalStates:0 TotalAssetParams:0 TotalAssets:0 TotalBoxes:0 TotalBoxBytes:0} VotingData:{VoteID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] SelectionID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] StateProofID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] VoteFirstValid:0 VoteLastValid:0 VoteKeyDilution:0}}, tried to spend {9999999999999})`,
}, data {AccountBaseData:{Status:Offline MicroAlgos:{Raw:9998000} RewardsBase:${rewardsBase} RewardedMicroAlgos:{Raw:0} AuthAddr:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ TotalAppSchema:{_struct:{} NumUint:0 NumByteSlice:0} TotalExtraAppPages:0 TotalAppParams:0 TotalAppLocalStates:0 TotalAssetParams:0 TotalAssets:0 TotalBoxes:0 TotalBoxBytes:0} VotingData:{VoteID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] SelectionID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] StateProofID:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] VoteFirstValid:0 VoteLastValid:0 VoteKeyDilution:0}}, tried to spend {9999999999999})`,
)
}
})
Expand Down
6 changes: 5 additions & 1 deletion src/types/algo-http-client-with-retry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ export class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {
}
// Only retry for one of the hardcoded conditions
if (
!(AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) || AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(err.status))
!(
AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) ||
AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) ||
('response' in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))
)
) {
throw err
}
Expand Down
23 changes: 23 additions & 0 deletions src/types/app-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,29 @@ describe('application-client', () => {
expect(indexes).toEqual([0, 1])
})

test('Sign transaction in group with different signer if provided', async () => {
const { algod, indexer, testAccount, generateAccount } = localnet.context
const signer = await generateAccount({ initialFunds: (1).algos() })
const transaction = (
await algokit.transferAlgos(
{
from: signer,
to: signer.addr,
amount: algokit.microAlgos(Math.ceil(Math.random() * 10000)),
skipSending: true,
},
algod,
)
).transaction
const { client } = await deploy(testAccount, algod, indexer)

await client.call({
method: 'call_abi_txn',
methodArgs: [{ transaction, signer }, 'test'],
sender: testAccount,
})
})

test('Construct transaction with abi encoding including foreign references not in signature', async () => {
const { algod, indexer, testAccount } = localnet.context
const { client } = await deploy(testAccount, algod, indexer)
Expand Down

0 comments on commit 58b7b98

Please sign in to comment.